use*_*135 14 spring-mvc spring-test-mvc spring-boot
我正在尝试新的Spring Boot 1.4 MVC测试功能.我有以下控制器.
@Controller
public class ProductController {
private ProductService productService;
@Autowired
public void setProductService(ProductService productService) {
this.productService = productService;
}
@RequestMapping(value = "/products", method = RequestMethod.GET)
public String list(Model model){
model.addAttribute("products", productService.listAllProducts());
return "products";
}
}
Run Code Online (Sandbox Code Playgroud)
我最小的ProductService实现是:
@Service
public class ProductServiceImpl implements ProductService {
private ProductRepository productRepository;
@Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@Override
public Iterable<Product> listAllProducts() {
return productRepository.findAll();
}
}
Run Code Online (Sandbox Code Playgroud)
ProductRepository的代码是:
public interface ProductRepository extends CrudRepository<Product,
Integer>{
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用新的@WebMvcTest来测试控制器.我的观点是百里香的teamplate.我的控制器测试是这样的:
@RunWith(SpringRunner.class)
@WebMvcTest(ProductController.class)
public class ProductControllerTest {
private MockMvc mockMvc;
@Before
public void setUp() {
ProductController productController= new ProductController();
mockMvc = MockMvcBuilders.standaloneSetup(productController).build();
}
@Test
public void testList() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/products"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.view().name("products"))
.andExpect(MockMvcResultMatchers.model().attributeExists("products"));
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在运行测试时我得到了这个错误.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through method 'setProductService' parameter 0: No qualifying bean of type [guru.springframework.services.ProductService] found for dependency [guru.springframework.services.ProductService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [guru.springframework.services.ProductService] found for dependency [guru.springframework.services.ProductService]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Run Code Online (Sandbox Code Playgroud)
我需要帮助来解决问题以正确测试ProductController.建议额外的andExpect()以更全面地测试控制器将受到高度赞赏.
提前致谢.
Ant*_*nio 21
谁有兴趣加载完整的应用程序应尝试使用@SpringBootTest结合@AutoConfigureMockMvc而不是@WebMvcTest.
我一直在努力解决这个问题,但最后我得到了完整的图片.
互联网上的许多教程, 以及我到目前为止发现的官方Spring文档,都说明你可以使用测试你的控制器@WebMvcTest; 这完全正确,但仍然省略了一半的故事.
正如这种注释的javadoc所指出的那样,@WebMvcTest仅用于测试您的控制器,并且根本不会加载所有应用程序的bean,这是设计的.
它甚至与显式的bean扫描注释不兼容@Componentscan.
我建议有人对这个问题感兴趣,阅读注释的完整javadoc(只有30行长,并且包含了浓缩的有用信息),但我将提取一些与我的情况相关的宝石.
使用此批注将全面禁用自动配置,改为适用有关MVC测试(即只配置
@Controller,@ControllerAdvice,@JsonComponent过滤器,WebMvcConfigurer和HandlerMethodArgumentResolver咖啡豆,但没有@Component,@Service或@Repository豆类).[...] 如果您要加载完整的应用程序配置并使用MockMVC,则应考虑@SpringBootTest与@AutoConfigureMockMvc此注释结合使用而不是此注释.
实际上,只有@SpringBootTest+ @AutoConfigureMockMvc修复了我的问题,所有其他使用的方法都@WebMvcTest无法加载一些必需的bean.
我收回了我对Spring文档所做的评论,因为当我使用a时,我并不知道有一个片段是隐含的@WebMvcTest; 实际上MVC切片文档清楚地表明并非所有应用程序都被加载,这是切片的本质.
测试切片是关于分割为测试创建的ApplicationContext.通常,如果您想使用MockMvc测试控制器,那么您肯定不想打扰数据层.相反,您可能想要模拟控制器使用的服务,并验证所有与Web相关的交互是否按预期工作.
And*_*son 15
您正在使用的@WebMvcTest同时还手动配置MockMvc实例.这没有意义,因为其中一个主要目的@WebMvcTest是MockMvc为您自动配置实例.此外,在您使用的手动配置中,standaloneSetup这意味着您需要完全配置正在测试的控制器,包括将任何依赖项注入其中.你没有做那导致了NullPointerException.
如果你想使用@WebMvcTest,我建议你这样做,你可以setUp完全删除你的方法,并MockMvc使用@Autowired字段注入一个自动配置的实例.
然后,控制ProductService多数民众赞成使用ProductController,您可以使用新的@MockBean注解来创建一个模拟ProductService,然后将被注入ProductController.
这些更改使您的测试类看起来像这样:
package guru.springframework.controllers;
import guru.springframework.services.ProductService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@WebMvcTest(ProductController.class)
public class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private ProductService productService;
@Test
public void testList() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/products"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.view().name("products"))
.andExpect(MockMvcResultMatchers.model().attributeExists("products"))
.andExpect(MockMvcResultMatchers.model().attribute("products",
Matchers.is(Matchers.empty())));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15537 次 |
| 最近记录: |