Java 具有Springbean依赖项的Junit/Mockito单元
我需要在ProductManager类(一个Springbean)中测试以下方法。productService是一个bean,并注入ProductManager类。我尝试使用Mockito编写Junit测试,但它一直在调用真实的productService.getProductIdList(email)方法,而不是mock。ProductService还有一个@PostConstruct。有人能告诉我我的测试代码出了什么问题吗Java 具有Springbean依赖项的Junit/Mockito单元,java,spring,junit,mockito,Java,Spring,Junit,Mockito,我需要在ProductManager类(一个Springbean)中测试以下方法。productService是一个bean,并注入ProductManager类。我尝试使用Mockito编写Junit测试,但它一直在调用真实的productService.getProductIdList(email)方法,而不是mock。ProductService还有一个@PostConstruct。有人能告诉我我的测试代码出了什么问题吗 @Named(ProductManager.NAME) public
@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;
}
}
@Named(ProductManager.NAME)
公共类产品经理{
@资源(名称=ProductService.name)
私人产品服务;
公共静态最终字符串NAME=“productManager”;
公共集getProducts(字符串电子邮件){
设置productList=productService.getProductIdList(电子邮件);
迭代器itr=productList.Iterator();
Set products=new HashSet();
乘积p=null;
while(itr.hasNext()){
p=getProduct(itr.next());
如果(p!=null){
产品.加入(p);;
}
}
退货产品;
}
公共产品getProduct(整数ProductId){
productp=productService.getProduct(productId);
返回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());
}
@测试
public void getProductByEmail(){
字符串电子邮件=”testfakeuser@gmail.com";
ProductService mockProductService=mock(ProductServiceImpl.class);
整数productId1=10000;
整数乘积ID2=10002;
产品p1=模拟(产品类别);
产品p2=模拟(产品类);
当(p1.getProductId())。然后返回(productId1);
当(p2.getProductId())。然后返回(productId2);
Set productIdSet=(Set)mock(Set.class);
productIdSet.add(productId1);
productIdSet.add(productId2);
迭代器productIdIterator=(迭代器)mock(迭代器.class);
when(productIdSet.iterator())。然后返回(productIdIterator);
当(mockProductService.getProductIdList(email)),然后返回(productIdSet);
when(productIdIterator.hasNext())。然后返回(true、true、false);
when(productIdIterator.next()).thenReturn(productId1.thenReturn(productId2);
当(productManager.getProduct(productId1)),然后返回(p1);
当(productManager.getProduct(productId2)),然后返回(p2);
Set products=productManager.getProducts(电子邮件);
资产质量(2,products.size());
}
我看不到将模拟ProductService设置到ProductManager对象的任何位置
您已经创建了一组复杂的相关对象,但没有要求ProductManager使用它。我看不到您在哪里将模拟ProductService设置为ProductManager对象
您已经创建了一组复杂的相关对象,但没有要求ProductManager使用它。我看不到您在哪里将模拟ProductService设置为ProductManager对象
您已经创建了一组复杂的相关对象,但没有要求ProductManager使用它。我看不到您在哪里将模拟ProductService设置为ProductManager对象
您创建了一组复杂的相关对象,但没有要求ProductManager使用它。我在回答自己的问题。我使用Spring ReflectionTestUtils解决了这个问题。它可以设置模拟依赖项。我引用了。我尝试了第二种解决方案,但没能成功。 在此测试中,productManager不会被模拟。这是一种真正的春豆。另一种方法是根本不使用Spring上下文,只使用Mockito RunWith(MockitoJUnitRunner.class)。在本例中,将模拟所有bean,包括productManager。我昨天做了一些研究,最好使用MockitoJUnitRunner.class,因为它可以避免重复代码,并且您可以完全控制您的测试环境。请阅读本文,了解如何使用MockitoJUnitRunner.class。这是明确和简单的
@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());
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:context test.xml”)
公共类ProductManagerTest{
@注入
私人产品经理;
@试验
public void getProductByEmail(){
字符串电子邮件=”testfakeuser@gmail.com";
ProductService mockProductService=mock(ProductServiceImpl.class);
整数productId1=10000;
整数乘积ID2=10002;
产品p1=模拟(产品类别);
产品p2=模拟(产品类);
p1.设置产品ID(产品ID 1);
p2.设置产品ID(产品ID 2);
Set productIdSet=(Set)mock(Set.class);
productIdSet.add(productId1);
productIdSet.add(productId2);
迭代器productIdIterator=(迭代器)mock(迭代器.class);
when(productIdSet.iterator())。然后返回(productIdIterator);
当(mockProductService.getProductIdList(email)),然后返回(productIdSet);
ReflectionTestUtils.setField(productManager,“mockProductService”,
(服务),;
when(productIdIterator.hasNext())。然后返回(true、true、false);
when(productIdIterator.next()).thenReturn(productId1.thenReturn(productId2);
当(productManager.getProduct(productId1)),然后返回(p1);
当(productManager.getProduct(productId2)),然后返回(p2);
Set products=productManager.getProducts(电子邮件);
资产质量(2,products.size());
}
}
我在回答我自己的问题。我使用Spring ReflectionTestUtils解决了这个问题。它可以设置模拟依赖项。我引用了。我尝试了第二种解决方案,但没能成功。
在此测试中,productManager不会被模拟。这是一种真正的春豆。另一种方法是根本不使用Spring上下文,只使用Mockito RunWith(MockitoJUnitRunner.class)。在本例中,将模拟所有bean,包括productManager。我昨天做了一些研究,最好使用MockitoJUnitRunner.class,因为它可以避免重复代码,并且您可以完全控制您的测试环境。请阅读本文,了解如何使用MockitoJUnitRunner.class