Jas*_*tes 4 aop unit-testing spring-mvc
好的,我们正在谈论Spring(3.2.0)MVC
我们有一个切入点定义为在"注释"周围触发,如下所示:
@Around("@annotation(MyAnnotation)")
public void someFunction() {
}
Run Code Online (Sandbox Code Playgroud)
然后在控制器中我们有:
@Controller
@Component
@RequestMapping("/somepath")
public class MyController {
@Autowired
private MyService service;
...
@MyAnnotation
@RequestMapping(value = "/myendpoint", method = RequestMethod.POST, produces = "application/json")
@ResponseBody
public Object myEndpoint(@RequestBody MyRequestObject requestObject, HttpServletRequest request, HttpServletResponse response) {
...
return service.doSomething(requestObject);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们有一个单元测试,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"../path/to/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class MyControllerTest {
private MockMvc mockMvc;
@InjectMocks
private MyController controller;
@Mock
private MyService myService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void myTest() {
MyRequest request = new MyRequest();
MyResponse response = new MyResponse();
String expectedValue = "foobar";
Mockito.when(myService.doSomething((MyRequest) Mockito.any())).thenReturn(response);
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/myendpoint");
String request = IOUtils.toString(context.getResource("classpath:/request.json").getURI());
builder.content(request);
builder.contentType(MediaType.APPLICATION_JSON);
mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.someKey").value(expectedValue));
Mockito.verify(myService, Mockito.times(1)).doSomething((MyRequest) Mockito.any());
}
}
Run Code Online (Sandbox Code Playgroud)
测试运行正常,但是注释(MyAnnotation)周围定义的方面不会执行.当端点由实际请求触发时(例如,在servlet容器中运行时),这执行得很好,但在测试中运行时不会触发.
这是MockMvc的一个特殊"功能",它不会触发方面吗?
仅供参考我们的applicationContext.xml配置为:
<aop:aspectj-autoproxy/>
Run Code Online (Sandbox Code Playgroud)
正如我所提到的,这些方面确实在现实中起作用,而不是在测试中.
任何人都知道如何解决这些问题?
谢谢!
好的..所以解决方案最终出现了......你猜对了..阅读文档:/
此外,您可以通过Spring配置将模拟服务注入控制器,以便继续专注于测试Web层.
所以最终的解决方案看起来像这样:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"testContext.xml","../path/to/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class MyControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
@Autowired
private MyService myService;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void myTest() {
MyRequest request = new MyRequest();
MyResponse response = new MyResponse();
String expectedValue = "foobar";
Mockito.when(myService.doSomething((MyRequest) Mockito.any())).thenReturn(response);
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/myendpoint");
String request = IOUtils.toString(context.getResource("classpath:/request.json").getURI());
builder.content(request);
builder.contentType(MediaType.APPLICATION_JSON);
mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.someKey").value(expectedValue));
Mockito.verify(myService, Mockito.times(1)).doSomething((MyRequest) Mockito.any());
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您只需为此测试定义一个上下文文件,该文件testContext.xml具有服务对象的模拟:
<bean id="myService" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.mypackage.MyService"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
重要的是MyService实例@Autowired进入测试,因此可以进行编排.
这允许您模拟出您喜欢的任何实例,无论它们是在服务类,方面等,只要您适当地命名bean.因此,在这种情况下,MyService将声明为:
@Component("myService")
public class MyService {
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6271 次 |
| 最近记录: |