因为我是 Spring Test MVC 的新手,所以我不明白这个问题。我从 http://markchensblog.blogspot.in/search/label/Spring 中获取了以下代码
变量 mockproductService
不是从 Application Context 注入(inject)的,它包含 null
值,同时使用 @Mock
注释并获取 Assets 错误。
我目前遇到的Assertion错误如下:
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)
注意:如果我使用 @Autowired
而不是 @Mock
,它工作正常。
测试 Controller 类
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 Long(1));
Product product2 = new Product();
product2.setId(new Long(2));
products.add(product1);
products.add(product2);
Mockito.when(mockproductService.findAllProducts()).thenReturn(products);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testMethod() throws Exception {
List<Product> products = new ArrayList<Product>();
Product product1 = new Product();
product1.setId(new Long(1));
Product product2 = new Product();
product2.setId(new Long(2));
products.add(product1);
products.add(product2);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/products");
this.mockMvc.perform(requestBuilder).
andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.model().attribute("Products", products))
//.andExpect(MockMvcResultMatchers.model().size(2))
.andExpect(MockMvcResultMatchers.view().name("show_products"));
}
}
Controller 类
@Controller
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("/products")
public String testController(ModelMap model){
model.addAttribute("Products",productService.findAllProducts());
return "show_products";
}
}
WebServletContext mvc-dispatcher-servlet.xml
<bean id="someDependencyMock" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.pointel.spring.test.ProductService" />
</bean>
<context:component-scan base-package="com.pointel.spring.test" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
最佳答案
对我来说,不清楚您从引用的博客源中获取的 Spring 和 Mockito 的组合应该如何按预期工作。至少我可以解释你的观察:
- 您的测试 (
this.mockMvc.perform()
) 正在 Spring 创建的 Web 应用程序上下文中运行。在该上下文中,ProductController
由 Spring (context:component-scan
) 实例化。productService
然后与您在mvc-dispatcher-servlet.xml
中创建的 Mockito 模拟 Autowiring 为someDependencyMock
。 - 如果您通过
@Autowired
注入(inject)mockproductService
,Spring 会从其上下文中注入(inject)someDependencyMock
实例。因此,您的Mockito.when()
调用在此实例上正常工作,如前所述,该实例已正确连接到ProductController
。 - 但是,如果您通过
@Mock
注入(inject)mockproductService
,Mockito 会注入(inject)的新实例ProductService
,不是 Spring 上下文之一,因为它对 Spring 一无所知。因此,您的Mockito.when()
调用不会对 Spring Autowiring 的模拟进行操作,因此someDependencyMock
保持未初始化状态。
所以我不清楚博客中的原始代码是如何工作的:
- 用
@InjectMocks
注释的productController
属性将由 Mockito 初始化,甚至正确连接到测试类中的mockproductService
。但是 Spring 对该对象一无所知,也不会在this.mockMvc.perform()
调用中使用它。所以我假设如果你只用@Autowired
注入(inject)mockproductService
你的测试会按预期工作,即使你同时删除了productController
属性和MockitoAnnotations.initMocks()
在您的测试类中调用。
关于java - Mockito 在使用@Mock 时将空值注入(inject) Spring bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16062842/