@Mocked太狠了,把类的所有的实例都Mock了。有时候我们希望一个类不同的实例有不同的Mock逻辑,怎么呢?
下面列举3种方法。还是以如何Mock类中的提到的AnOrdinaryClass为例。
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import org.junit.Assert;
import org.junit.Test;
//一个类多个实例的Mock
public class OneClassManyInstanceMockingTest {
//Mock 方法一:把实例传入Expectations的构造函数。
// 适用场景:只Mock实例的部分方法,对注释的实例类产生影响,对其他实例不产生影响。
@Test
public void testMocking1(){
AnOrdinaryClass instance1 = new AnOrdinaryClass();
AnOrdinaryClass instance2 = new AnOrdinaryClass();
//直接把实例传给Expectations的构造函数即可Mock这个实例
new Expectations(instance1, instance2){
{
instance1.ordinaryMethod();
result = 20;
instance2.ordinaryMethod();
result = 200;
}
};
AnOrdinaryClass instance3 = new AnOrdinaryClass();
Assert.assertTrue(instance1.ordinaryMethod() == 20); //instance1 的ordiaryMethod 被Mock了
Assert.assertTrue(instance2.ordinaryMethod() == 200); //instance2 的ordiaryMethod 被Mock了
Assert.assertTrue(instance3.ordinaryMethod() == 2); //instance3 不受影响,执行原逻辑
}
//Mock 方法二:用@Mocked
// 适用场景:类的所实例都需要Mock,但不同实例也能保留不同Mock的逻辑。
@Test
public void testMocking2(@Mocked AnOrdinaryClass instance1,@Mocked AnOrdinaryClass instance2 ){
new Expectations(){
{
instance1.ordinaryMethod();
result = 20;
instance2.ordinaryMethod();
result = 200;
}
};
AnOrdinaryClass instance3 = new AnOrdinaryClass();
Assert.assertTrue(instance1.ordinaryMethod() == 20); //instance1 的ordiaryMethod 被Mock了
Assert.assertTrue(instance2.ordinaryMethod() == 200); //instance2 的ordiaryMethod 被Mock了
Assert.assertTrue(instance3.ordinaryMethod() == 0); //instance3 受@mock的影响,@mock会把类的所有方法都mock,返回类型为基本数据类型的返回0
}
//Mock 方法三:用@Injectable。
// 适用场景:不是类的所实例都需要Mock,被@injectable注释实例会被mock,其他实例执行原有逻辑,不同实例也能保留不同Mock逻辑。
@Test
public void testMocking3(@Injectable AnOrdinaryClass instance1, @Injectable AnOrdinaryClass instance2){
new Expectations(){
{
instance1.ordinaryMethod();
result = 20;
instance2.ordinaryMethod();
result = 200;
}
};
AnOrdinaryClass instance3 = new AnOrdinaryClass();
Assert.assertTrue(instance1.ordinaryMethod() == 20); //instance1 的ordiaryMethod 被Mock了
Assert.assertTrue(instance2.ordinaryMethod() == 200); //instance2 的ordiaryMethod 被Mock了
Assert.assertTrue(instance3.ordinaryMethod() == 2); //instance3 不受Injectable的影响,因为@Injectable只影响某一个实例。
}
}