何时使用Mocktio中的when()

时间:2015-10-28 08:23:56

标签: java unit-testing testing junit mockito

我正在用JUnit和Mockito编写单元测试。让我们说我有以下测试课程:

@Mock(name="myService")
private myServiceClass myService;

@InjectMocks
private myClassIWantToTest classUnderTest;

final myModelClass myModel = new myModelClass();

@Before
private void setUp(){
    MockitoAnnotiations.initMocks(this);
}

@Test 
private void testSomething(){
    myModel.setCode("someCode");

    final MyDataClass myData = new MyDataClass();
    myData.setCode("someCode");

    doReturn("someCode").when(myModel.getCode());
    doReturn(myModel).when(myService.getModelByCode("someCode"));

    assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData);
    verify(myService.getModelByCode(eq("someCode")), atLeastOnce());
}

我的getDataByCode方法classUnderTest将模型转换为数据,它应该具有相同的代码。对我来说有点模糊的是,单元测试应该封装来自所有依赖项的classUnderTest。但现在我有一个问题。我使用setter方法myDatamyModel来设置值。问题是我为DoReturn添加myModel,但问题是,它不是注入的模拟。我尝试测试的方法很遗憾没有字段,它在方法中初始化,所以我无法真正解决它。

主要的是,当例如myModel的设定者不再工作时,我的测试如上所示,将不再起作用。我想我有三个问题:

  1. 我需要多大程度的隔离测试类?我不需要将setter用于assertEquals吗?

  2. 还有另一种处理对象的方法,这些对象是在我想测试的方法中初始化的吗?处理此事的最佳方法是什么?

  3. 另外,构建这个的好模式是什么?我目前在测试方法中初始化我期望的myData结果。问题是这是一个相当简短的例子,但是我有一些课程,我有很多对象和方法。

1 个答案:

答案 0 :(得分:1)

听起来你的主要问题是你要测试的类的设计。但之前有一些事情:

myModel.setCode("someCode");
doReturn("someCode").when(myModel.getCode());

这没有意义。这不是模拟,所以......在这里没有意义。如果它是一个模拟器,调用setter将毫无用处。

assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData);

也很奇怪。你想调用getDataByCode,为什么eq?做吧。叫它。写:

assertEquals(classUnderTest.getDataByCode("someCode"), myData);

Mockito-Matchers在您想要验证某些内容时很好,但通常您不会将它们用作实际方法调用的参数。

verify(myService.getModelByCode(eq("someCode")), atLeastOnce());

这段代码真的可以编译吗?不应该......

verify(myService, atLeastOnce()).getModelByCode(eq("someCode"));

因此,尽可能实际隔离单元测试是个好主意。您参与测试的外部问题越少,测试就越好。

  

我试图测试的方法很遗憾没有一个字段,它   在方法中初始化这个,所以我无法真正解决它。

这听起来像是一种代码味道,但如果没有相关的实际代码,很难说......