返回值是模拟期望值时的单元测试

时间:2018-10-05 20:02:08

标签: unit-testing mockito

所以我有一个看起来像这样的方法:

public Foo method() { ... return service.get(); }

service是该类的外部依赖项。

我的测试代码:

Foo mockServiceResponse = Mockito.mock(Foo.class); when(service.get()).thenReturn(mockServiceResponse);

在单元测试中,我注入了一个使用Mockito创建的模拟并为when设置了service.get(),所以我的问题是,如何测试method的返回值? 如果我只是检查mockServiceResponse是否等于method(),该测试就不会检查太多,因为是否有人将method更改为:

public Foo method() { ... Foo f = service.get(); f.setId(null); return f; }

我的测试仍会通过,这显然是错误的,那么我应该如何测试呢?

澄清:我要测试的是,method不会更改从service.get()返回的对象(意味着,我希望第二个存根无法通过我的测试),问题是模拟对象只是忽略了调用它们的方法(例如setId())而没有通过测试。

2 个答案:

答案 0 :(得分:0)

您将执行以下操作:

Service service = mock(Service.class);
Foo aResponse = new Foo(1);
when(service.get()).thenReturn(aResponse);

MyClass subject = new MyClass(service);

Foo result = subject.method();
assertNull(result.getId());

答案 1 :(得分:0)

您可以使用Mockito的verifyNoMoreInteractionsverifyZeroInteractions来断言没有对服务响应对象进行任何调用。

@Test
public void should_not_mutate_response() {
    // given
    Service mockService = Mockito.mock(Service.class);
    Foo mockServiceResponse = Mockito.mock(Foo.class);
    when(mockService.get()).thenReturn(mockServiceResponse);

    SubjectUnderTest subjectUnderTest = new SubjectUnderTest(mockService);

    // when
    Foo result = subjectUnderTest.method();

    //then
    Mockito.verifyZeroInteractions(mockServiceResponse);
}

或者,如果您毕竟希望与响应对象进行某些特殊的交互,则:

@Test
public void should_set_id_on_response() {
    // given
    ...

    // when
    ...

    // then
    Mockito.verify(mockServiceResponse).setId(ArgumentMatchers.anyInt());
    Mockito.verifyNoMoreInteractions(mockServiceResponse);
}