java - 无法模拟 Spring Data Jpa 的 void 方法
问题描述
我有下面的 void 方法,我希望得到模拟。
public void updateEmployee(EmployeeDto dto) {
Employee d = convertToEntity(dto);
employeeRepository.updateEmployee(d.getEmployeeName(), d.getEmployeeDescription(),
d.getEmployeeOwnerEmployeeId(), d.getEmployeeCode(), d.getStatus());
}
但我得到了错误。
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
at com.xxx.EmployeeServiceTest.test_UpdateEmployee(EmployeeServiceTest.java:120)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
测试方法
@RunWith(PowerMockRunner.class)
@PrepareForTest({StatusEnum.class})
public class EmployeeServiceTest {
@Mock
private Employee employeeMock;
@InjectMocks
private EmployeeServiceImpl employeeServiceImpl;
@Mock
private EmployeeRepository employeeRepositoryMock;
@Mock
private EmployeeDto employeeDtoMock;
@Mock
private StatusEnum statusEnum;
@Mock
private Exception ex;
List<String> employeeNames = new ArrayList<>();
@Before
public void setup() {
// To mock static methods or class
mockStatic(StatusEnum.class);
}
@Test
public void test_UpdateEmployee() {
doNothing().when(employeeServiceImpl).saveEmployee(any(EmployeeDto.class));
employeeServiceImpl.updateEmployee(employeeDtoMock);
/*doAnswer((i) -> {
System.out.println("Employee setName Argument = " + i.getArgument(0));
assertTrue("Pankaj".equals(i.getArgument(0)));
return null;
}).when(employeeServiceImpl).updateEmployee(employeeDtoMock);*/
}
}
解决方案
这里的例外对我来说似乎很清楚,employeeServiceImpl
似乎不是一个模拟。你是如何实例化它的?使用Mockito.mock
还是@Mock
在现场?
- - 编辑
为了澄清我的答案,在@Before
(或您的测试类中的等效项)使用 mockito 实例化您的服务:
this.employeeService = Mockito.mock(EmployeeService.class);
或者
@Mock
private EmployeeService employeeService;
然后它应该工作。
--- 编辑所以看看你是如何注入你的模拟的,我想我可能会明白发生了什么。事实上@InjectMocks
并没有使你的EmployeeService a mock
. 它允许 mockito 知道让您的框架创建 bean 并注入您在其中创建的 mock。
在这里,如果您已将存储库声明为这样的模拟
@Mock
private EmployeeRepository employeeRepository;
然后EmployeeRepository
将在employeeService
实例内部注入一个类型的模拟,这不是模拟。
然后,如果它实际上是您要模拟的存储库,则应将其放入when
测试中,例如:
doNothing().when(employeeRepository).saveEmployee(any(EmployeeDto.class));
employeeServiceImpl.saveEmployee(employeeDtoMock);
然后调用你的服务将进入你的服务saveEmployee
函数,但是当它到达一个模拟的存储库时,它会按预期工作。
如果它实际上是您要模拟的整个服务,则使用@Mock
而不是@InjectMocks
.
推荐阅读
- unix - 每连续两行合并
- windows - 使 cmd / powershell / windows 使用单独的 tesseract 安装,而不是来自 Chocolatey 的安装
- c++ - 无法使用 isdigit() 检测字符串中的数字
- python - 通过递归就地修改
- go - DynamoDB、STS 和 golang
- c# - UWP 使用 NamedPipes 向 Windows 服务发送消息
- wordpress - 使用 Gutenberg 作为编辑器时无法访问 WooCommerce 中的产品评论
- javascript - 在 jQuery 中寻找 Touchstart / Touchend 的解决方法
- javascript - 如何将 koa-session 数据传递给 NextJS 中的页面组件?
- r - 绘图时,如何过滤掉ggplot2中总和<10的值?