是否在测试之间重置作为Spring Bean提供的Mockito模拟?

vc6uscn9  于 2022-11-08  发布在  Spring
关注(0)|答案(2)|浏览(146)

我有一个使用Spring依赖注入的Java应用程序,我想模拟一个bean,并验证它是否接收到某些方法调用。
问题是Mockito没有在测试之间重置mock,所以我不能正确地验证对它的方法调用。
我的受试单位:

public class MyClass {
  @Resource
  SomeClientClass client;

  public void myMethod() {
    client.someMethod();
  }
}

单元测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = UnitTestConfig.class)
public class MyClassTest {
  @Resource
  SomeClientClass client;

  @Test
  public void verifySomething() {
    // ...
    Mockito.verify(client).publish();
  }
}

最后,

@Configuration
public class UnitTestConfig {
  @Bean
  SomeClientClass client() {
    return Mockito.mock(SomeClientClass.class);
  }
}

虽然我可以通过手动重置测试之间的模拟来解决这个问题,但我想知道是否有更干净/更惯用的方法。

gkn4icbw

gkn4icbw1#

我不得不在开头加上一句:

@BeforeEach
void setup() {
     Mockito.reset(...mockBeans);
     ...
}
k10s72fa

k10s72fa2#

作者没有解释为什么他需要它,我可以把更多的细节。结合Spring的依赖注入与Mockito以这种方式不是最好的方法。
这会导致错误,因为相同的Mock会在不同的测试之间被重用!这意味着verify()将无法正常工作。它会累积不同测试的方法调用。例如,你会得到“Wanted 1 time:“-“But was 2 times”。
在Mockito中,最通用的解决方案是使用@InjectMocks。这个注解做了两件重要的事情:
1.实际上是将所有的@Mock字段注入到用@InjectMocks注解的类中
1.重置每个@Mock注解的类。(因此,verify()不会累积来自不同测试的调用)
程式码范例:

@RunWith(MockitoJUnitRunner.class)
public class SomeSpringConverterTest {

@InjectMocks
private SomethingToJsonNodeSpringConverter someSpringConverter;
@Mock
private SomethingDatamodelService someDatamodelService;

@Test
public void convertOriginalContainerTest() {
    SomethingContainer someContainer = buildSomeContainer("aa", "bb");
    Mockito.when(someDatamodelService.getAttributes()).thenReturn(Arrays.asList("aa", "bb"));
    JsonNode node = someSpringConverter.convert(someContainer, JsonNode.class);
    Mockito.verify(someDatamodelService.getAttributes());
    assertTrue(node.get("aa") != null);
}

@Test
public void convertOriginalContainerTest() {
    SomethingContainer someContainer = buildSomeContainer("aa", "bb");
    Mockito.when(someDatamodelService.getAttributes()).thenReturn(Arrays.asList("aa", "bb"));
    JsonNode node = someSpringConverter.convert(someContainer, JsonNode.class);
    Mockito.verify(someDatamodelService.getAttributes());
    assertTrue(node.get("bb") != null);
}

}

相关问题