我有一个Spring MVC应用程序。我要测试此控制器:
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {
"classpath:testDatabaseContext.xml"
})
public class TimeControllerTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Mock
private AutorisationService autorisationService;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void should_OK() throws Exception {
doReturn(User.builder().build()).when(autorisationService).findById(any(Date.class),anyLong(), 1L);
mockMvc.perform(get("/time/2")
.contentType(APPLICATION_JSON))
.andExpect(status().isOk());
}
}
但是运行测试时出现此错误:
org.mockito.exceptions.misusing.NullInsteadOfMockException:
Argument passed to when() is null!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
Also, if you use @Mock annotation don't miss openMocks()
答案 0 :(得分:1)
我看到了无法正常运行的几种原因:
A-仅靠@Mock不足以初始化模拟。您需要:
但是我认为这还不够,这使我进入了:
B-您的控制器看起来是由spring管理的,而您模拟的AutorisationService却不受。
我假设您的控制器使用了应该由spring注入的AutorisationService。
您在这里有几种选择:
@InjectMocks
private SomeController someController;
@Mock
private AutorisationService autorisationService;
@Before
public void setup() {
MockitoAnnotations.initMocks();
this.mockMvc = MockMvcBuilders.standaloneSetup(someController).build();
}
请注意standaloneSetup方法:此处的想法是您没有使用spring上下文(然后可以删除顶部的注释)。
有种骇客,但我经常使用。
您必须提供一个带有AutorisationService类型的bean的自定义spring上下文,但是该类是由嘲讽提供的。
// All all other beans necessary
// You can use whatever you need in your context : @ComponentScan("somepackage"), @Import(Config1.class, Config2.class), @ImportResource("context.xml"), @Bean methods ...
@Configuration
class SpringWithMockitoConfig {
@Bean
AutorisationService autorisationService() {
return Mockito.mock(AutorisationService.class);
}
}
然后,您的测试将受到两个限制:
使用此解决方案,您不需要真正的AutorisationService依赖的bean(我假设是Dao,DataSource等)。
基本上只有mvc部分。