菲尔兹不匹配,但测试仍然通过。 [Mockito测试]

时间:2017-02-14 00:12:58

标签: java unit-testing spring-boot junit mockito

我有以下测试设置。我不明白测试是如何成功通过的,因为用户被设置为" Dummy。"

@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");

    }

}

2 个答案:

答案 0 :(得分:3)

Tom在评论中回答:

  

为什么你期望的不是nullSomeRandomClass被模拟,因此在调用setUser时显然没有设置任何内容。为什么要这样呢?这就是模拟的重点。

请记住,模拟的实现不是真实的,特别是未被调用的调用将返回虚拟值,例如null0或空字符串。

答案 1 :(得分:1)

除了Tom在评论中已经说过的内容之外,这个测试还在测试你的模拟,而不是你的实际实现。由于您模拟了SomeRandomClass,因此您的测试应验证是否正在调用该方法。在这种情况下,您应该在致电SomeRandomClass.setRandom()时测试是否调用setUser(),同样,您应该在致电SomeRandomClass.getRandom()时测试是否调用getUser()

例如:

@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的行为。