摩擦图和方法调用之间的差异



我有一个关于在Java中使用Mockito的问题。我将附加相似代码的两个块:第一个,效果很好

package controller;
import model.DatabaseModel;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
public class TestController {
    JSONObject jsonObj1;
    JSONArray testArr;
    @Mock
    private DatabaseModel testDB;
    @InjectMocks
    private Controller controller;
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        jsonObj1 = new JSONObject();
        jsonObj1.put("name", "Bar");
        testArr = new JSONArray();
        testArr.put(jsonObj1);
        when(testDB.getActivites()).thenReturn(testArr);
    }
    @Test
    public void testServerCon() {
        ArrayList<String> testServer = new ArrayList<>();
        testServer.add("Bar");
        assertEquals(testServer, controller.getAllActivites());
    }
}

和第二个,这实际上是行不通的:

package controller;
import model.DatabaseModel;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class TestController2 {
    JSONObject jsonObj1;
    JSONArray testArr;
    DatabaseModel testDB;
    Controller controller;
    @Before
    public void setup() {
        jsonObj1=new JSONObject();
        jsonObj1.put("name", "Bar");
        testArr=new JSONArray();
        testArr.put(jsonObj1);
        controller=new Controller();
        testDB=mock(DatabaseModel.class);
        when(testDB.getActivites()).thenReturn(testArr);
        verify(testDB).getActivites();
    }
    @Test
    public void testServerCon(){
        ArrayList<String> testServer=new ArrayList<>();
        testServer.add("Bar");
        assertEquals(testServer, controller.getAllActivites());
    }
}

当我使用第二种验证方法时,我会发现该方法从未被调用的错误,所以我想知道我缺少什么?我在网上查找了教程,有些使用注释,有些则使用方法调用,但是如果我没记错的话,它们应该相同,所以我在这里缺少什么?

在您的第一个示例中,@InjectMocks注释会导致Controller的实例用模拟的DatabaseModel

在您的第二个示例中,您像这样构造Controller ...

controller=new Controller();

...但是您永远不会将模拟的Database Model注入Controller的这一实例。因此,当您调用controller.getAllActivites()时,您的控制器永远不会使用模拟的DatabaseModel。如果您可以将DatabaseModel注入Controller,则可以实现与第一个示例中相同的结果。例如:

testDB=mock(DatabaseModel.class);
// constructor injection
controller=new Controller(testDB);
// setter injection
controller=new Controller();
controller.setDatabaseModel(testDB);

注意:即使您从设置方法中删除verify(testDB).getActivites(),测试也会使其断言失败,除非您实际上将模拟的DatabaseModel提供给controller

您正在第二版中的setup方法中进行verify ...

@Before
public void setup() {
    jsonObj1=new JSONObject();
    jsonObj1.put("name", "Bar");
    testArr=new JSONArray();
    testArr.put(jsonObj1);
    controller=new Controller();
    testDB=mock(DatabaseModel.class);
    when(testDB.getActivites()).thenReturn(testArr);
    verify(testDB).getActivites(); // REMOVE THIS LINE
}

这次没有什么可以打电话给错误的。

您可能想将此线移入您的测试方法中,例如...

@Test
public void testServerCon(){
    ArrayList<String> testServer=new ArrayList<>();
    testServer.add("Bar");
    assertEquals(testServer, controller.getAllActivites());
    verify(testDB).getActivites();
}

相关内容

  • 没有找到相关文章

最新更新