【问题标题】:The return entity of mocked repository call is returning null模拟存储库调用的返回实体返回 null
【发布时间】:2019-11-07 09:27:13
【问题描述】:

代码sn-p根据参数检索实体。

public void updateNotification(String status, Entity entity ) {
        Entity entity1 = null;
        try {
            switch (status) {
            case "AX":
                entity1 = this.Repository.findByTypeAndParams(
                        1, entity.getParam1(), entity.getParam2(),
                        entity.getParam3());
                if (entity1!= null) {
                    entity1.setCurrentStatusKey("SET");
                    updateEntity(entity1);
                } else {
                    LOGGER.debug("");
                }
                break;

上述代码的测试用例:

@RunWith(SpringJUnit4ClassRunner.class)
public class ServiceTest {
    @InjectMocks
    CVService cVServiceMock;

    @Mock
    RepositoryMock repositoryMock;

     @Test
            public void testUpdateOut() {
                Entity entity1 = new Entity ();
                entity1.setType(2);
                Mockito.when(repositoryMock.findByTypeAndParams(any(Integer.class), any(String.class),
                        any(String.class), any(String.class))).thenReturn(entity1);
                cVServiceMock.updateNotification("AX", entity1);
            }

从测试用例执行时,entity1 始终为 null 而不是模拟实体, 我在这里做错了什么?

【问题讨论】:

  • 考虑添加minimal reproducible example 或至少添加完整的测试(包括模拟创建和其他注释)和被测类的相关部分(方法签名、相关字段、构造函数)。跨度>
  • 你能展示一下notificationServiceMock是如何初始化的吗?最好将所有类都粘贴到服务和测试中。
  • 请说明RepositoryMock是如何创建的。

标签: java spring-boot spring-data-jpa mockito mockmvc


【解决方案1】:

正如另一个StackOverflow MariuszS' answer about Mocking static methods with Mockito所说的:

在 Mockito 之上使用 PowerMockito

[...]

更多信息:

PowerMockito 添加了更多功能,它允许模拟私有方法、静态方法等。

有了这个,你也许应该模拟一个 Repository 的实例:

// In your test method
PowerMockito.mockStatic(Repository.class);

别忘了给你的测试类添加注解:

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class) // Since you are using SpringBoot
@PrepareForTest(Repository.class)
@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*", "javax.security.*"}) // Avoid certain classloading related issues, not mandatory

在我的示例中,Mockito.when()PowerMockito.doReturn(...).when(...) 替换。它可能如下所示:

@Test
public void testUpdateOut() {
    Entity entity1 = new Entity ();
    entity1.setType(2);
    PowerMockito.mockStatic(Repository.class);

    PowerMockito.doReturn(entity1).when(
        Repository.class,
        "findByTypeAndParams", // The name of the method
        Mockito.anyInt(), // The arguments
        Mockito.anyString(),
        Mockito.anyString(),
        Mockito.anyString()
    );

    // Your test
    notificationServiceMock.updateNotification("AX", entity1);

    // And at the end of the test:
    PowerMockito.verifyStatic(); // It will verify that all statics were called one time
}

请注意,我将您的any(Integer.class)any(String.class) 分别替换为anyInt()anyString()

我希望这会有所帮助!

【讨论】:

  • 我不认为Repository.findByTypeAndParams 是一个静态方法。只是 OP 没有使用 Java 约定来命名他的字段。
  • @second 也许你是对的,在这种情况下,mockStatic()verifyStatic() 是没用的。我会等他的答复。
猜你喜欢
  • 2021-12-08
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多