Spring Aspect没有在单元测试中触发

好的,我们正在谈论Spring(3.2.0)MVC

我们定义了一个切入点,以在注释周围“触发”,如下所示:

@Around("@annotation(MyAnnotation)")

public void someFunction() {

}

然后在控制器中,我们有:

@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);

}

}

然后我们有一个如下的单元测试:

@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());

}

}

该测试运行良好,但是围绕注释(MyAnnotation)定义的方面未执行。当端点由 实际

请求触发时(例如,在servlet容器中运行时),这执行得很好,但在测试中运行时,则不会触发。

这是MockMvc的特定“功能”,它不会触发方面吗?

仅供参考,我们的applicationContext.xml配置为:

<aop:aspectj-autoproxy/>

正如我所提到的,这些方面实际上是在现实中起作用的,只是在测试中没有。

有谁知道如何激发这些方面的?

谢谢!

回答:

好的..所以解决方案最终是由您自己提出的..您猜对了..阅​​读文档:/

http://docs.spring.io/spring-framework/docs/3.2.0.BUILD-

SNAPSHOT/reference/htmlsingle/#spring-mvc-test-

framework

此外,您可以通过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());

}

}

然后,您只需为此测试定义一个上下文文件,testContext.xml其中包含服务对象的模拟:

<bean id="myService" class="org.mockito.Mockito" factory-method="mock">

<constructor-arg value="com.mypackage.MyService"/>

</bean>

重要的是,MyService实例已@Autowired进入测试,因此可以进行编排。

这允许您模拟出您喜欢的任何实例,无论它们是否在服务类,方面等中,只要您适当地命名Bean。因此,在这种情况下,MyService将声明为:

@Component("myService")

public class MyService {

...

以上是 Spring Aspect没有在单元测试中触发 的全部内容, 来源链接: utcz.com/qa/430599.html

回到顶部