【问题标题】:Fields don't match but the test was still passed. [Mockito Test]字段不匹配,但测试仍然通过。 [模拟测试]
【发布时间】:2017-07-02 03:06:03
【问题描述】:

我设置了以下测试。由于用户设置为“虚拟”,我不明白测试如何成功通过。

@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 时它显然没有实际设置任何东西。为什么要这样做?这就是模拟的意义所在。
  • @Tom 您的评论是正确答案。如果您将其发布为答案,我将投票赞成。
  • @DavidWallace 随意自己做,我不回答这样的问题。谢谢你:)。
  • @Tom 是的,你说得对。我不应该期待什么。我是测试世界的新手,在理解 Mock 之前试图弄清楚为什么我的代码不起作用。不过这篇文章对我帮助很大:stackoverflow.com/questions/2277039/how-do-mock-frameworks-work

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


【解决方案1】:

Tom 在 cmets 中回答:

你为什么期待null以外的东西? SomeRandomClass 被嘲笑,所以在调用 setUser 时它显然没有实际设置任何东西。为什么要这样做?这就是模拟的意义所在。

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

【讨论】:

    【解决方案2】:

    除了 Tom 在 cmets 中已经说过的内容之外,此测试是测试您的模拟,而不是您的实际实现。由于您模拟了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 的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      相关资源
      最近更新 更多