繁体   English   中英

具有Spring Bean依赖项的Junit / Mockito单元

[英]Junit/Mockito unit with Spring bean dependencies

我需要在Spring的ProductManager类中测试以下方法。 productService一个bean,并注入到ProductManager类中。 我尝试使用Mockito编写Junit测试,但是它一直调用真正的productService.getProductIdList(email)方法而不是模拟方法。 ProductService也有一个@PostConstruct。 谁能启发我我的测试代码出了什么问题?

@Named(ProductManager.NAME)
public class ProductManager {

@Resource(name = ProductService.NAME)
private ProductService productService;    

    public static final String NAME = "productManager";

    public Set<Product> getProducts(String email) {
        Set<Integer> productList = productService.getProductIdList(email);
        Iterator<Integer> itr = productList.iterator();
        Set<Product> products = new HashSet<Product>();
        Product p = null;
        while (itr.hasNext()) {
            p = getProduct(itr.next());
            if (p != null) {
                products.add(p);
            }
        }
        return products;
    }


    public Product getProduct(Integer ProductId) {
        Product p = productService.getProduct(productId);
        return p;
    }

}

到目前为止,我已经遵循了Junit测试代码。

@Test
public void getProductByEmail(){

    String email = "testfakeuser@gmail.com";

    ProductService  mockProductService = mock(ProductServiceImpl.class);

    Integer productId1 = 10000;
    Integer productId2 = 10002;

    Product p1 = mock(Product.class);
    Product p2 = mock(Product.class);
    when(p1.getProductId()).thenReturn(productId1);
    when(p2.getProductId()).thenReturn(productId2);

    Set<Integer> productIdSet = (Set<Integer>)mock(Set.class);
    productIdSet.add(productId1);
    productIdSet.add(productId2);
    Iterator<Integer> productIdIterator = (Iterator<Integer>)mock(Iterator.class);
    when(productIdSet.iterator()).thenReturn(productIdIterator);        
    when(mockProductService.getProductIdList(email)).thenReturn(productIdSet);
    when(productIdIterator.hasNext()).thenReturn(true, true, false);
    when(productIdIterator.next()).thenReturn(productId1).thenReturn(productId2);
    when(productManager.getProduct(productId1)).thenReturn(p1);
    when(productManager.getProduct(productId2)).thenReturn(p2);

    Set<Product> products = productManager.getProducts(email);
    assertEquals(2, products.size());

}

我看不到将模拟的ProductService设置到ProductManager对象的任何位置。

您已经创建了一组复杂的相关对象,但是没有要求ProductManager使用它。

我在回答我自己的问题。 我使用Spring ReflectionTestUtils解决了这个问题。 它可以设置模拟依赖。 我引用了http://romiawasthy.blogspot.com/2012/03/autowired-mockobjects-for-junits.html 我尝试了第二个解决方案,但无法使其正常工作。 在此测试中,不会模拟productManager。 这是一个真正的春豆。 另一种方法是根本不使用Spring上下文,仅使用Mockito RunWith(MockitoJUnitRunner.class)。 在这种情况下,将模拟所有bean,包括productManager。 昨天我做了一些研究,最好使用MockitoJUnitRunner.class,因为它可以使重复代码无效,并且您可以完全控制测试环境。 请查看本文以了解如何使用MockitoJUnitRunner.class http://www.jayway.com/2012/02/25/mockito-and-dependency-injection/ 这很简单。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:context-test.xml")
public class ProductManagerTest {

    @Inject
    private ProductManager productManager;
    @Test
    public void getProductByEmail(){

        String email = "testfakeuser@gmail.com";

        ProductService  mockProductService = mock(ProductServiceImpl.class);

        Integer productId1 = 10000;
        Integer productId2 = 10002;

        Product p1 = mock(Product.class);
        Product p2 = mock(Product.class);
        p1.setProductId(productId1);
        p2.setProductId(productId2);


        Set<Integer> productIdSet = (Set<Integer>)mock(Set.class);
        productIdSet.add(productId1);
        productIdSet.add(productId2);
        Iterator<Integer> productIdIterator = (Iterator<Integer>)mock(Iterator.class);
        when(productIdSet.iterator()).thenReturn(productIdIterator);        
        when(mockProductService.getProductIdList(email)).thenReturn(productIdSet);

        ReflectionTestUtils.setField(productManager, "mockProductService",
            mockProductService); 

        when(productIdIterator.hasNext()).thenReturn(true, true, false);
        when(productIdIterator.next()).thenReturn(productId1).thenReturn(productId2);
        when(productManager.getProduct(productId1)).thenReturn(p1);
        when(productManager.getProduct(productId2)).thenReturn(p2);

        Set<Product> products = productManager.getProducts(email);
        assertEquals(2, products.size());

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM