我有一个关于在Java中使用Mockito的问题。我将附上2个类似代码的块:第一个,效果很好
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);
注意:即使你从setup方法中删除verify(testDB).getActivites()
,测试也会失败它的断言,除非你实际上向DatabaseModel
提供了模拟的controller
。
你在第二版中用verify
方法做setup
......
@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();
}