JMockit的常用注解
1. @Tested
- 用于标识一个被测对象的实例,只能作用于具体类,而不能作用于接口,因为一个接口可能有多个实现类,被测试的只能是实现该接口的某一个具体的类
- 通过@Tested标签标识的被测对象实例,将会在测试方法执行之前被JMockit初始化。
- 可通过@Injectable注解对被测对象的构造函数进行改写。如果没有@Injectable,则采用原有代码进行初始化。
- 被@Tested注解的对象,其域对象将自动被@Injectable注解生成的对象进行初始化
- 如果@Tested的fullyInitialized=true,则被测对象的所有参数都需要被初始化。
2. @Injectable
- 标识只有一个指定的被测对象的内部变量被mock,其他和被mock实例采用相同对象的实例不受影响。
- 被@Tested注解的对象,其域对象将自动被@Injectable注解生成的对象进行初始化
3. @Mocked
- 用于全局变量或方法的参数,标识一个指定的class的实例或被测对象的参数被Mock掉。JMockit根据Expectation方法中的设置来初始化被Mock对象的值。
- 所有对象(基本类型和Array除外)都可以通过@Mocked标识被Mock掉。
- 当一个被测对象的参数被Mock的时候,执行测试时,该参数将不再按照原有的代码来实例化,而是将实例化的工作委托给JMockit来完成。
- 被Mock的对象的除了继承自Object的方法之外的所有方法(包括构造函数、静态函数等)都会被JMockit重写。
4. @Capturing
- 标识一个被Mock的类及其子类均被Mock。
- 可以通过maxInstances方法来限定最大有多少层子类也被mock
举个栗子(代码片段):
DemoServiceImpl:
import org.springframework.beans.factory.annotation.Autowired;
public class DemoServiceImpl implements DemoService {
@Autowired
private DemoDao demoDao;
@Autowired
private StockDao stockDao;
/**
* 更新库存
*
* @return
*/
public int updateCount(int id, int count) {
//...... UPDATE Database
return stockDao.queryStock(id) - count;//返回数量
}
}
DemoServiceImplAutowireTest:
import mockit.*;
import mockit.integration.junit4.JMockit;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Autowired对象 Mock测试
*/
@RunWith(JMockit.class)
public class DemoServiceImplAutowireTest {
/**
* 被测试的对象,只能是具体类,而不能是接口,因为一个接口可能有多个实现类
* 所有带有@Injectable的实例均被自动注入该实例中
*/
@Tested
private DemoServiceImpl noteService;
/**
* 自动注入到noteService中,只有一个StockDao的特定实例stockDao被MOCK掉
*/
@Injectable
private StockDao stockDao;
@Test
public void test() {
// 1. record 录制期望值
new Expectations() {
{
stockDao.queryStock(anyInt);// mock这个方法,无论传入任何Int类型的值,都返回同样的值,达到黑盒的效果
result = 50;
times = 1;
}
};
// 2. replay 调用
Assert.assertEquals(50 - 10, noteService.updateCount(1, 10)); //验证结果
//3.校验是否只调用了一次。
new Verifications() {
{
stockDao.queryStock(anyInt);
times = 1;
}
};
}
}