【问题标题】:NullPointerException when mocking repository JUnit模拟存储库 JUnit 时出现 NullPointerException
【发布时间】:2020-09-04 13:04:59
【问题描述】:

我创建了一个带有控制器、服务和存储库层的基本 Rest API。我现在正在尝试为通过产品 ID 查找产品的服务层方法编写单元测试。但是,当我运行测试时,它会在我尝试模拟存储库 findById() 方法的行中抛出 NullPointerException。

服务层的getProductById()方法如下:

public Product getProductById(String id){ return productRepository.findById(id).orElse(null); }

我的服务层测试类:

package com.product.Services;

import com.product.Entities.Product;
import com.product.Repositories.ProductRepository;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)

class ProductServiceTest {

   @InjectMocks
   ProductService productService;

   @Mock
   ProductRepository productRepository;

   @Test
   void getProductById() throws Exception {

      Product product = new Product();
      product.setId("001");
      product.setName("TV");
      product.setPrice(999.99);

      when(productRepository.findById("001").orElse(null)).thenReturn(product);
      assertEquals(product,productService.getProductById("001"));
   }
}

附上调试器显示的图片:

【问题讨论】:

  • 您是否尝试过公开类/测试功能?你用的是什么模拟版本?
  • 更改为 public 似乎并没有解决它。 mockito 版本是 org.mockito:mockito-core:3.3.3
  • 嗨,克里斯。您是否尝试过在 @InjectMocks 之前声明 @Mock 注释?
  • @CarlosMancilla 订单无关紧要。但 Benoit 在他的回答中提出的建议是有道理的。

标签: java testing junit rest


【解决方案1】:

问题是这里使用了 2 个不同版本的 JUnit: org.junit.jupiter.api.Test 来自 JUnit5,而 org.junit.runner.RunWith 来自 JUnit4。

RunWith 在 JUnit5 中不再存在。

在这种特定情况下,我将使用 JUnit4 - 即使用注释 org.junit.Test(而不是 org.junit.jupiter.api.Test)来注释您的测试。

How to use Mockito with JUnit5 提供了其他有效的解决方案。

【讨论】:

  • 摆弄依赖项和导入,一旦我设法让所有东西都与 Junit5 匹配,它就开始工作了。不太确定是哪一个变化促成了它,但干杯队友!
【解决方案2】:

JUnit 5 使用 @ExtendWith(SpringExtension.class) 注解,你能不能更改 @RunWith 注解再试一次?

【讨论】:

  • 是的,这是我需要做的改变的一部分。
【解决方案3】:

您应该模拟findById 调用,而不是与orElse 链接的表达式:

when(productRepository.findById("001")).thenReturn(product);

【讨论】:

  • 正确,但这不会神奇地使productRepository 不为空。
  • 试过了,改了也没有用。认为问题在于存储库为空而不是语句本身。
猜你喜欢
  • 1970-01-01
  • 2020-11-20
  • 1970-01-01
  • 2019-03-24
  • 2021-05-08
  • 2014-05-03
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多