【问题标题】:NullPointerException from service when use repository [closed]使用存储库时来自服务的 NullPointerException [关闭]
【发布时间】:2022-01-18 23:27:55
【问题描述】:

我有一个关于单元测试的问题。我正在编写测试以检查服务是否正确保存数据(即不重复) 有一个服务类有几个字段,我们对 TypeRepository 字段感兴趣。在保存它的方法中调用并使用 find 方法......在这种情况下,当我运行测试时,我得到 NullPointerException。我不知道在这种情况下有什么帮助。我会很感激你的帮助

服务

@Service
@Slf4j
public class Service {
    ... 
    ...
    final RiskRepo riskRepo;
    ...
    ...
    private Limit validate(Limit newLimit) {
   
        RiskType.Value typeValue
                = riskRepo.findDistinctLimitTypeValueByLimitType(newLimitType);
                      //  ^--- exception
        
        switch (typeValue) { <-- warning can be null  
            case CONTY: {
                ...
                break;
            }

    ...
}

回购

public interface Repo extends JpaRepository<Limit, Integer> {


    @Query("SELECT DISTINCT r.Value from Type r WHERE r.limit=?1")
    RiskType.Value findDistinctValueByLimit(String limitType);
}

测试



 @Test
    public void test_validate() {
        Limit newLimit = Limit.builder()
                .riskType(...)
                ......build();

        limitService.create(newLimit);
        List<Limit>  limits = limitRepository.findAllByRiskTypeAndEntityAndLimitTypeAndUnitAndActive(
                newLimit.getRiskType(), newLimit.getEntity(), newLimit.getLimitType(),newLimit.getUnit(),newLimit.getActive());
        Assert.assertEquals(1, limits.size());
    }

【问题讨论】:

  • 如果你在做单元测试,那么你需要模拟RiskRepo。你这样做吗?
  • 这里的信息太少,无法回答这个问题。哪里抛出异常?完整的测试是什么样的,你的服务是什么样的。所有这些,关键的信息都丢失了。在当前状态下,无法回答问题。

标签: java spring unit-testing mockito


【解决方案1】:

您可以为您的测试类编写更多代码,因为这可能是测试配置问题或不在这些代码段上的问题。但首先,请确保您在服务上注入存储库,它看起来不像,因此使用 @Autowired 注释存储库属性或创建构造函数并在他内部启动存储库实例。另一个可能导致问题的事情是你的服务方法是私有的,它必须是公共的,否则只有服务类可以访问它。

关于测试,通常当我做这些类型的测试时,它们可以被模拟或集成。

模拟测试:

您必须在服务测试类上方使用 @RunWith(MockitoJunitRunner.class) 之类的注解。然后注入服务并使用@Mock(repo)和@InjectMocks(服务)模拟您正在使用的存储库。

@RunWith(MockitoJUnitRunner.class)
public class YourTestClass {

@InjectMocks
private LimitService service;

@Mock
private LimitRepository repository;

@Test
public void test_validate(){
  
  when(this.repository...).thenReturn(...);

  this.service.doSomething();

  verify(this.repository).doSomething(...);
  verifyNoMoreInteractions(this.repository);
}

集成测试:

这里您要做的几乎与存储库测试相同,不同之处在于您需要调用将调用存储库方法的SERVICE。您需要像存储库测试一样配置您的类以运行上下文。

@RunWith(SpringRunner.class)
@SpringBootTest
public class EmployeeRestControllerIntegrationTest {

    @Autowired
    private LimitService service;

    // write test cases here (such as your own, asserting the result of the service method return)
}

所以这些将是这两种服务测试的解决方案,现在如果您需要测试存储库,我建议查看 Spring Boot 存储库测试。

【讨论】:

  • 感谢您的回复,很好地解释了如何在这种情况下工作,我还浏览了网站,发现了一个非常方便的@Before。 .在这种情况下,它有所帮助,感谢您指出解决此问题的正确方法。
【解决方案2】:

我能够通过使用@Before方法初始化存储库并将测试数据写入数据库来解决问题

@Before
    public void setup() {
  Type type = new Type(
               data..);
        TypeRepository.save(type);

}

【讨论】:

    猜你喜欢
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    相关资源
    最近更新 更多