【问题标题】:Unit testing when the returned value is a mock expectation返回值是模拟期望时的单元测试
【发布时间】:2018-10-05 20:02:07
【问题描述】:

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

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

service 是类的外部依赖。

我的测试代码:

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

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

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

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

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

【问题讨论】:

  • 不确定是什么问题。您只需确定方法调用的结果就是您告诉模拟返回的结果。
  • 1.你为什么要嘲笑响应,而不是创建一个真实的并检查这个真实的是否返回。 2. 测试就是这样:测试。它不应该是一个数学证明并检查代码可能做的每一个奇怪的不切实际的事情。如果有人也改变了测试怎么办? 3.如果你真的想保持这种方式,你可以使用static.javadoc.io/org.mockito/mockito-core/2.22.0/org/mockito/…
  • 我不清楚你真正想测试什么。我得到的印象(但这只是一个假设),你真正想要测试的是返回语句之前的省略号“...”表示的代码中的逻辑 - 而你模拟 service.get( ) 调用只会让您的测试看到模拟的内容,但不会洞察该方法的其他代码是否正确。这是你的问题的目的吗?
  • 补充说明,希望现在更好

标签: unit-testing mockito


【解决方案1】:

你会做这样的事情:

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());

【讨论】:

  • @jwismar 我也有类似的情况,但是这个单元测试值得吗?除了从模拟返回的值之外,它并没有真正测试任何东西。我们能说它“测试起来太简单”了吗?
【解决方案2】:

您可以使用 Mockito 的 verifyNoMoreInteractions 或 verifyZeroInteractions 断言没有调用服务响应对象。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多