我设置了以下测试。我不明白测试是如何成功通过的,因为用户被设置为"假人"。
@RunWith(MockitoJUnitRunner.class)
public class TodoServiceAbstractImplTest
{
@InjectMocks
TodoServiceAbstractImpl todoServiceAbstractImpl = new TodoServiceAbstractImpl();
@Mock
SomeRandomClass someRandomClass;
@Mock
TodoServiceAbstract todoServiceAbstract;
@Test
public void testRetrieveTodo_usingAMock(){
todoServiceAbstractImpl.setUser("Dummy"); //Set the user to be "Dummy" already
assertEquals(null,todoServiceAbstractImpl.getUser()); //Why is the user is still null?
}
}
以下是相关类。我创建它们来测试Mockito,因为我仍在Spring Boot中学习测试。
SomeRandomClass的定义:
public class SomeRandomClass{
private String field;
public SomeRandomClass(){
}
public SomeRandomClass(String field){
setRandom(field);
}
public void setRandom(String field){
this.field = field;
}
public String getRandom(){
return field;
}
}
抽象类的定义:
public abstract class TodoServiceAbstract {
@Autowired
private SomeRandomClass RandomUser;
public TodoServiceAbstract(){
//RandomUser = new SomeRandomClass();
}
public void setUser(String user){
this.RandomUser.setRandom(user);
}
public String getUser(){
return RandomUser.getRandom();
}
public abstract List<String> retrieveTodos(String user);
}
抽象实现的定义
public class TodoServiceAbstractImpl extends TodoServiceAbstract{
public List<String> retrieveTodos(String user){
if(user == getUser()){
return Arrays.asList("item 1", "item 2",
"item 3");
}
return Arrays.asList("Random item");
}
}
姆在评论中回答:
你为什么期待
null
之外的东西?SomeRandomClass
被嘲笑,因此在调用setUser
时显然没有设置任何内容。为什么呢?这就是模拟的意义所在。
请记住,模拟实现不是真实的,特别是未存根调用将返回虚拟值,例如 null
、 0
或空字符串。
除了 Tom 在评论中已经说过的内容之外,这个测试是测试你的模拟,而不是你的实际实现。由于您模拟了SomeRandomClass
,因此您的测试应该验证是否正在调用该方法。在这种情况下,您应该测试在调用setUser()
时是否调用SomeRandomClass.setRandom()
,同样,您应该测试在调用getUser()
时是否调用SomeRandomClass.getRandom()
。
例如:
@Test
public void getUser_shouldUseGetRandom() {
when(someRandomClass.getRandom()).thenReturn("data");
assertEquals("data", todoServiceAbstractImpl.getUser());
}
要测试setUser()
您可以执行以下操作:
@Test
public void setUser_shouldUseSetRandom() {
todoServiceAbstractImpl.setUser("data");
verify(someRandomClass).setRandom("data");
}
通过模拟/存根,您可以为TodoServiceAbstractImpl
编写适当的单元测试,而不必采取SomeRandomClass
的行为。