Проблема с тестированием Spring MVC slice в SpringBoot 1.4
Я пробую новые функции тестирования 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";
}
}
моя минимальная реализация 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();
}
}
код ProductRepository является:
public interface ProductRepository extends CrudRepository<Product,
Integer>{
}
Я пытаюсь использовать новый @WebMvcTest для тестирования conroller. Мой взгляд-это thymeleaf 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"));
}
}
но при запуске теста я получаю эту ошибку.
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: {}
мне нужен помогите решить проблему для правильного тестирования ProductController. Предложения для дополнительных andExpect () для более тщательного испытания регулятора сильно будет оценено.
спасибо заранее.
2 ответов
вы используете @WebMvcTest
при ручной настройке MockMvc
экземпляра. Это не имеет смысла как одна из основных целей @WebMvcTest
автоматически настроить MockMvc
экземпляр для вас. Кроме того, в ручной конфигурации вы используете standaloneSetup
это означает, что вам нужно полностью настроить тестируемый контроллер, включая введение в него любых зависимостей. Вы не делаете то, что вызывает NullPointerException
.
если вы хотите использовать @WebMvcTest
, и я бы рекомендовал вам это сделать, вы можете удалить свой setUp
метод полностью и автоматически настроен MockMvc
экземпляр вводится вместо
кто заинтересован в загрузке полного приложения, должен попробовать использовать @SpringBootTest
в сочетании с @AutoConfigureMockMvc
, а не @WebMvcTest
.
я боролся с проблемой довольно долго, но, наконец, я получил полную картину.
Многие учебники в интернете,а также официальная Весенняя документация, которую я нашел до сих пор , укажите, что вы можете проверить свои контроллеры с помощью @WebMvcTest
; это совершенно правильно, все еще опуская половину истории хотя.
Как указано в Javadoc такой аннотации, @WebMvcTest
предназначен только для тестирования контроллеров, и не будет загружать все бобы вашего приложения на всех, а это по дизайну.
Он даже несовместим с явными аннотациями сканирования bean, такими как @Componentscan
.
я предлагаю всем, кто интересуется этим вопросом, прочитать полный javadoc аннотации (которая составляет всего 30 строк и набита сжатой полезной информацией), но я извлеку пару драгоценных камней отношение к моей ситуации.
использование этой аннотации отключит полную автоматическую конфигурацию и вместо этого применит только конфигурацию, относящуюся к тестам MVC (т. е.
@Controller
,@ControllerAdvice
, ,WebMvcConfigurer
иHandlerMethodArgumentResolver
бобы, но не@Component
,@Service
или@Repository
бобы). [...] если вы хотите загрузить полную конфигурацию приложения и использовать MockMVC, вы должны считать@SpringBootTest
в сочетании с@AutoConfigureMockMvc
вместо этой аннотации.
и на самом деле, только @SpringBootTest
+ @AutoConfigureMockMvc
исправлена моя проблема, все другие подходы, которые используют @WebMvcTest
не удалось загрузить некоторые из необходимых компонентов.
редактировать
я беру свой комментарий, который я сделал о весенней документации, потому что я не знал, что a фрагмент подразумевалось, когда один использует @WebMvcTest
; на самом деле в документации MVC slice это ясно что не все приложение загружается, что по самой природе среза.
пользовательский тестовый срез с Spring Boot 1.4
тестовая нарезка - это сегментация ApplicationContext, созданного для вашего теста. Как правило, если вы хотите протестировать контроллер с помощью MockMvc, конечно, вы не хотите беспокоиться о слое данных. Вместо этого вы, вероятно, захотите издеваться над службой, которую использует ваш контроллер и убедитесь, что все веб-взаимодействие работает должным образом.