模拟存储库 bean 始终为空
Mocking Repository bean is always null
我已经尝试测试控制器行为几个小时了。问题是我必须模拟存储库,它总是变成空的。
从结构上看,我有一个控制器,它有两个注入的服务,这些服务使用两个不同的存储库。
所以我可以测试我的控制器和我的服务逻辑行为我必须模拟存储库对某些查询的响应。
我正在努力实现它,如下所示:
@WebMvcTest({ WorkspaceRestController.class })
@Tag(Tags.COMPONENT)
@ActiveProfiles(PfSpringProfiles.TEST)
public class WorkspaceRestControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private IWorkSpaceRepository workSpaceRepository;
@MockBean
private IExpertSystemRepository expertSystemRepository;
@InjectMocks
private IExpertSystemService expertSystemService;
@InjectMocks
private IAsyncWorkService asyncWorkspaceService ;
@InjectMocks
private IWorkspaceService workspaceService;
@InjectMocks
WorkspaceRestController workspaceRestController;
@BeforeAll
public void intTests() {
}
@Test
public void checkRetrievedContentIsNotnull() throws Exception {
// Given
Mockito.when(workSpaceRepository.getAllWorkspaces())
.thenReturn(new WorkSpaceRepositoryMock().getAllWorkspaces(WorkSpaceRepositoryMock.CASE_FULL));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID));
// When
MvcResult result = mockMvc.perform(get("/rest/v2/ws-list")).andExpect(request().asyncStarted()).andDo(print())
.andReturn();
// Then
mockMvc.perform(asyncDispatch(result)).andDo(print());
// .andExpect( content().string(mapper.writeValueAsString(fullWorkspaceResponseSet)));
}
}
然而,每当我启动 JUnit 测试时,workSpaceRepository
始终为空。
我该怎么办?
在我的控制器、服务和存储库的代码下方
工作区存储库
@Repository
public interface IWorkSpaceRepository extends JpaRepository<Workspace, Long> {
/**
* This method fetches the list of all available workspaces. It could return an empty list.
*
* @return List<Workspace> The list of all workspaces found
*/
@Transactional
@Modifying(clearAutomatically = false)
@Query(value = "SELECT ws from Workspace ws JOIN FETCH ws.configuration")
List<Workspace> getAllWorkspaces();
}
工作区服务
@Service
public class WorkspaceServiceImp implements IWorkspaceService {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceServiceImp.class);
private static final String ERROR_AT_DELETE_WORKSPACE_METHOD = "Error at deleteWorkspace() method";
private static final String ERROR_AT_CREATE_WORKSPACE_METHOD = "Error at createWorkspace() method";
@Autowired
private IWorkSpaceRepository workSpaceRepository;
@Autowired
private WorkspaceMapper workspaceMapper;
@Autowired
private IExpertSystemService expertSystemService;
@Autowired
private IPatternInfosService patternInfosService;
@Autowired
private IPatternFieldsService patternFieldsService;
@Autowired
private IConfigurationService configurationService;
// service methods implementation is ommited
}
控制器
@RestController
@RequestMapping(path = "/rest/ws/")
@Api("WS Service Rest")
@Validated
public class WorkspaceRestController implements RestApiPing {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceRestController.class);
@Autowired
private IWorkspaceService workspaceService;
@Autowired
private AsyncWorkspaceService asyncWorkspaceService;
// rest api definition here omited
}
我得到的堆栈跟踪:
java.lang.NullPointerException
at com.bnpp.pf.diligense.controller.WorkspaceRestControllerTest.checkRetrievedContentIsNotnull(WorkspaceRestControllerTest.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:72)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute[=14=](EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
将 @RunWith(SpringRunner.class)
添加到您的测试 class 如果您是 运行 junit4 以便 Mockito 工作。
对于 junit5,等效项是 @ExtendWith(SpringExtension.class)
,但它包含在 @WebMvcTest
中,因此不需要显式声明。
我已经尝试测试控制器行为几个小时了。问题是我必须模拟存储库,它总是变成空的。
从结构上看,我有一个控制器,它有两个注入的服务,这些服务使用两个不同的存储库。
所以我可以测试我的控制器和我的服务逻辑行为我必须模拟存储库对某些查询的响应。
我正在努力实现它,如下所示:
@WebMvcTest({ WorkspaceRestController.class })
@Tag(Tags.COMPONENT)
@ActiveProfiles(PfSpringProfiles.TEST)
public class WorkspaceRestControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private IWorkSpaceRepository workSpaceRepository;
@MockBean
private IExpertSystemRepository expertSystemRepository;
@InjectMocks
private IExpertSystemService expertSystemService;
@InjectMocks
private IAsyncWorkService asyncWorkspaceService ;
@InjectMocks
private IWorkspaceService workspaceService;
@InjectMocks
WorkspaceRestController workspaceRestController;
@BeforeAll
public void intTests() {
}
@Test
public void checkRetrievedContentIsNotnull() throws Exception {
// Given
Mockito.when(workSpaceRepository.getAllWorkspaces())
.thenReturn(new WorkSpaceRepositoryMock().getAllWorkspaces(WorkSpaceRepositoryMock.CASE_FULL));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID));
Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID))
.thenReturn(new ExpertSystemRepositoryMock()
.getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID));
// When
MvcResult result = mockMvc.perform(get("/rest/v2/ws-list")).andExpect(request().asyncStarted()).andDo(print())
.andReturn();
// Then
mockMvc.perform(asyncDispatch(result)).andDo(print());
// .andExpect( content().string(mapper.writeValueAsString(fullWorkspaceResponseSet)));
}
}
然而,每当我启动 JUnit 测试时,workSpaceRepository
始终为空。
我该怎么办?
在我的控制器、服务和存储库的代码下方
工作区存储库
@Repository
public interface IWorkSpaceRepository extends JpaRepository<Workspace, Long> {
/**
* This method fetches the list of all available workspaces. It could return an empty list.
*
* @return List<Workspace> The list of all workspaces found
*/
@Transactional
@Modifying(clearAutomatically = false)
@Query(value = "SELECT ws from Workspace ws JOIN FETCH ws.configuration")
List<Workspace> getAllWorkspaces();
}
工作区服务
@Service
public class WorkspaceServiceImp implements IWorkspaceService {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceServiceImp.class);
private static final String ERROR_AT_DELETE_WORKSPACE_METHOD = "Error at deleteWorkspace() method";
private static final String ERROR_AT_CREATE_WORKSPACE_METHOD = "Error at createWorkspace() method";
@Autowired
private IWorkSpaceRepository workSpaceRepository;
@Autowired
private WorkspaceMapper workspaceMapper;
@Autowired
private IExpertSystemService expertSystemService;
@Autowired
private IPatternInfosService patternInfosService;
@Autowired
private IPatternFieldsService patternFieldsService;
@Autowired
private IConfigurationService configurationService;
// service methods implementation is ommited
}
控制器
@RestController
@RequestMapping(path = "/rest/ws/")
@Api("WS Service Rest")
@Validated
public class WorkspaceRestController implements RestApiPing {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceRestController.class);
@Autowired
private IWorkspaceService workspaceService;
@Autowired
private AsyncWorkspaceService asyncWorkspaceService;
// rest api definition here omited
}
我得到的堆栈跟踪:
java.lang.NullPointerException
at com.bnpp.pf.diligense.controller.WorkspaceRestControllerTest.checkRetrievedContentIsNotnull(WorkspaceRestControllerTest.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:72)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute[=14=](EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
将 @RunWith(SpringRunner.class)
添加到您的测试 class 如果您是 运行 junit4 以便 Mockito 工作。
对于 junit5,等效项是 @ExtendWith(SpringExtension.class)
,但它包含在 @WebMvcTest
中,因此不需要显式声明。