mockito_使用Mockito模拟自动装配的字段

本文介绍了如何使用Mockito来模拟Spring自动装配的字段,以提高测试的可隔离性和可重用性。通过使用Mockito的特殊注解,可以在不依赖Spring上下文的情况下,对测试对象的私有字段进行初始化和模拟。这种方法允许在不同的测试方法中重置和重新配置模拟对象,适用于重复测试和参数化测试场景。
摘要由CSDN通过智能技术生成
mockito

mockito

依赖注入是诸如Spring和EJB之类的Control容器反转的非常强大的功能。 将注入的值封装到私有字段中总是一个好主意。 但是,自动连线字段的封装会降低可测试性。

我喜欢Mockito解决此问题以模拟自动装配字段的方式。 将在示例中进行解释。 (此博客文章希望您对Mockito语法有点熟悉,但是它具有足够的自我描述性。)

这是测试模块的第一个依赖项。 是Spring单例豆。 该类将在测试中被模拟。

@Repository
public class OrderDao {
	public Order getOrder(int irderId){
		throw new UnsupportedOperationException("Fail is not mocked!");
	}
}

这是测试类的第二个依赖项。 它也是Spring组件。 该类将在测试中被侦听(部分嘲笑)。 其方法calculatePriceForOrder将保持不变。 第二种方法将被存根。

@Service
public class PriceService {
	public int getActualPrice(Item item){
		throw new UnsupportedOperationException("Fail is not mocked!");
	}

	public int calculatePriceForOrder(Order order){
		int orderPrice = 0;
		for (Item item : order.getItems()){
			orderPrice += getActualPrice(item);
		}
		return orderPrice;
	}
}

这是正在测试的课程。 它自动装配上面的依赖项。

@Service
public class OrderService {

	@Autowired
	private PriceService priceService;

	@Autowired
	private OrderDao orderDao;

	public int getOrderPrice(int orderId){
		Order order = orderDao.getOrder(orderId);
		return priceService.calculatePriceForOrder(order);
	}
}

最后是测试示例。 它使用字段级别的注释:

  • @InjectMocks –实例化测试对象实例,并尝试将用@Mock@Spy注释的字段注入到测试对象的私有字段中
  • @Mock –创建其注释字段的模拟实例
  • @Spy –为带注释的字段实例创建间谍
public class OrderServiceTest {
	private static final int TEST_ORDER_ID = 15;
	private static final int TEST_SHOES_PRICE = 2;   
	private static final int TEST_SHIRT_PRICE = 1;

	@InjectMocks
	private OrderService testingObject;

	@Spy
	private PriceService priceService;

	@Mock
	private OrderDao orderDao;

	@BeforeMethod
	public void initMocks(){
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void testGetOrderService(){
		Order order = new Order(Arrays.asList(Item.SHOES, Item.SHIRT));
		Mockito.when(orderDao.getOrder(TEST_ORDER_ID)).thenReturn(order);

		//notice different Mockito syntax for spy
		Mockito.doReturn(TEST_SHIRT_PRICE).when(priceService).getActualPrice(Item.SHIRT);
		Mockito.doReturn(TEST_SHOES_PRICE).when(priceService).getActualPrice(Item.SHOES);

		//call testing method
		int actualOrderPrice = testingObject.getOrderPrice(TEST_ORDER_ID);

		Assert.assertEquals(TEST_SHIRT_PRICE + TEST_SHOES_PRICE, actualOrderPrice);
	}
}

那么当您运行此测试时会发生什么:

  1. 首先,TestNG框架使用@BeforeMethod批注并调用initMocks方法
  2. 此方法调用特殊的Mockito调用( MockitoAnnotations.initMocks(this) )以初始化带注释的字段。 没有此调用,这些对象将为null 。 这种方法的常见错误是忘记了该调用。
  3. 当所有测试字段都填充有所需值时,将调用test。

该示例不包括Spring上下文创建,并且Spring的注释在这里仅作为针对生产代码使用的示例。 测试本身不包含对Spring的任何依赖关系,并且会忽略其所有注释。 实际上,可以使用EJB批注代替它,也可以针对普通(非IoC托管)私有字段运行它。

开发人员倾向于将MockitoAnnotations.initMocks(this)调用视为不必要的开销。 但这实际上非常方便,因为它可以重置测试对象并重新初始化模拟。 您可以使用它为例

  • 当您使用相同的带注释实例的各种测试方法来确保各种测试运行不使用相同的记录行为时
  • 当使用重复/参数化测试时。 例如,您可以将此调用包含在测试方法本身中,并接收间谍对象作为测试参数(作为测试用例的一部分)。 与TestNG @DataProvider功能结合使用时,此功能非常性感(将在其他博客文章中对此进行解释)。

@Spy注释对象可以通过两种方式创建

  • 如果存在默认(非参数化)构造函数,则由Mockito框架自动进行
  • 或显式初始化(​​例如,当只有非默认构造函数时)

@InjectMocks注释的测试对象也可以显式初始化。

参考:http://lkrnac.net/博客上,使用Mockito模拟来自JCG合作伙伴Lubos Krnac的自动连线字段

翻译自: https://www.javacodegeeks.com/2014/02/use-mockito-to-mock-autowired-fields.html

mockito

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值