当使用@Mock时,将Null值注入到Spring bean中吗?

由于我是Spring Test MVC的新手,所以我不了解此问题。我从http://markchensblog.blogspot.in/search/label/Spring中获取了以下代码

变量mockproductService不是从Application Context中注入的,它null在使用@Mock注释和获取资产错误时包含值。

我当前遇到的断言错误如下:

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它,则工作正常。

测试控制器类

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

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随后与您创建的模拟的Mockito自动连接mvc-dispatcher-servlet.xml的someDependencyMock

如果注入mockproductServicevia @Autowired,SpringsomeDependencyMock将从其上下文注入实例。因此,您的Mockito.when()呼叫可以在此实例上正常工作,该实例已ProductController如前所述正确连接到。

但是,如果注入mockproductServicevia @Mock,则Mockito会注入的新实例ProductService,而不是Spring上下文的实例,因为它完全不了解Spring。因此,您的Mockito.when()呼叫无法在由Spring自动连线的模拟上进行操作,从而someDependencyMock保持未初始化状态。

因此,关于该博客的原始代码是如何工作的,我仍然不清楚:

  • productController带注释的属性@InjectMocks将由Mockito初始化,甚至正确地连接到mockproductService测试类中的。但是Spring对这个对象一无所知,并且不会在this.mockMvc.perform()调用中使用它。因此,我假设即使删除测试类中的属性和调用,您是否mockproductService@Autowired按预期进行测试即可。productControllerMockitoAnnotations.initMocks()

以上是 当使用@Mock时,将Null值注入到Spring bean中吗? 的全部内容, 来源链接: utcz.com/qa/400987.html

回到顶部