我正在使用Spring-boot测试(通过JUnit4和Spring MockMvc)一个REST服务适配器.适配器只是将对其发出的请求传递给另一个REST服务(使用自定义RestTemplate),并将其他数据附加到响应中.
我想运行MockMvc测试来执行控制器集成测试,但是想要RestTemplate使用模拟覆盖控制器中的控件,以允许我预定义第三方REST响应并防止它在每次测试期间被命中.我已经能够通过实例化一个做到这一点MockMvcBuilders.standAloneSetup(),并把它传递给与在此列出注入模拟测试控制器后(及以下我的设置),但我无法做到使用相同的MockMvcBuilders.webAppContextSetup().
我已经阅读了其他几篇文章,其中没有一篇文章回答了如何实现这一目标的问题.我想将实际的Spring应用程序上下文用于测试,而不是单独使用,以防止应用程序可能增长时出现任何差距.
编辑:我使用Mockito作为我的模拟框架,并试图将其中一个模拟注入上下文.如果没有必要,那就更好了.
控制器:
@RestController
@RequestMapping(Constants.REQUEST_MAPPING_PATH)
public class Controller{
@Autowired
private DataProvider dp;
@Autowired
private RestTemplate template;
@RequestMapping(value = Constants.REQUEST_MAPPING_RESOURCE, method = RequestMethod.GET)
public Response getResponse(
@RequestParam(required = true) String data,
@RequestParam(required = false, defaultValue = "80") String minScore
) throws Exception {
Response resp = new Response();
// Set the request params from the client request
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(Constants.PARAM_DATA, data); …Run Code Online (Sandbox Code Playgroud) 我有宁静的服务,我想在不连接数据库的情况下对它们进行单元测试,因此我编写了这段代码:
@Before
public void setup() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
adminDao = mock(AdminDaoImpl.class);
adminService = new AdminServiceImpl(adminDao);
}
@Test
public void getUserList_test() throws Exception {
User user = getTestUser();
List<User> expected = spy(Lists.newArrayList(user));
when(adminDao.selectUserList()).thenReturn(expected);
mockMvc.perform(get("/admin/user"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(1)))
;
}
Run Code Online (Sandbox Code Playgroud)
该服务被调用,但我的问题是这行代码
when(adminDao.selectUserList()).thenReturn(expected);
Run Code Online (Sandbox Code Playgroud)
不工作,我的意思是它真的调用了 adminDao.select 方法,因此从数据库中获取结果。我不想要的。你知道如何模拟方法调用吗?
好的,我们正在谈论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 …Run Code Online (Sandbox Code Playgroud) 由于我是Spring Test MVC的新手,我不明白这个问题.我从http://markchensblog.blogspot.in/search/label/Spring中获取了以下代码
变量mockproductService不是从Application Context注入的,它null在使用@Mock注释和获取assetion错误时包含值.
我目前遇到的断言错误如下:
java.lang.AssertionError: Model attribute 'Products' expected:<[com.pointel.spring.test.Product@e1b42, com.pointel.spring.test.Product@e1f03]> but was:<[]>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.ModelResultMatchers$2.match(ModelResultMatchers.java:68)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
at com.pointel.spring.test.ProductControllerTest.testMethod(ProductControllerTest.java:84)
Run Code Online (Sandbox Code Playgroud)
注意:如果我使用@Autowired而不是@Mock它工作正常.
测试控制器类
RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations={"classpath:mvc-dispatcher-servlet.xml"})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class})
public class ProductControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@InjectMocks
private ProductController productController;
@Mock
//@Autowired
private ProductService mockproductService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
List<Product> products = new ArrayList<Product>();
Product product1 = new Product();
product1.setId(new …Run Code Online (Sandbox Code Playgroud) 当我一起使用webAppContextSetup时,我很难让Mockito和MockMvc一起工作.我很好奇,如果是因为我以一种他们从未想过的方式混合这两者.
资料来源:https://github.com/zgardner/spring-boot-intro/blob/master/src/test/java/com/zgardner/springBootIntro/controller/PersonControllerTest.java
这是我正在运行的测试:
package com.zgardner.springBootIntro.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static java.lang.Math.toIntExact;
import static org.hamcrest.Matchers.is;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import com.zgardner.springBootIntro.Application;
import com.zgardner.springBootIntro.service.PersonService;
import com.zgardner.springBootIntro.model.PersonModel;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class PersonControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext; …Run Code Online (Sandbox Code Playgroud) mockito ×4
java ×2
spring ×2
spring-boot ×2
unit-testing ×2
aop ×1
junit ×1
junit4 ×1
mockmvc ×1
spring-mvc ×1
spring-test ×1