gpt4 book ai didi

unit-testing - Spring Aspect 未在单元测试中触发

转载 作者:行者123 更新时间:2023-12-05 01:06:45 25 4
gpt4 key购买 nike

好的,我们说的是 Spring (3.2.0) MVC

我们有一个切入点定义为“围绕”一个注释触发,如下所示:

@Around("@annotation(MyAnnotation)")
public void someFunction() {

}

然后在 Controller 中我们有:
@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

Furthermore, you can inject mock services into controllers through Spring configuration, in order to remain focused on testing the web layer.



所以最终的解决方案是这样的:
@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 {
...

关于unit-testing - Spring Aspect 未在单元测试中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19690907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com