抽象类被称为使用abstract关键字声明的类, 该类可能包含也可能不包含abstract方法。在Java中, 无法实例化抽象类, 但可以将其子类化。它还可以具有静态字段和静态方法。
在本节中, 我们将讨论抽象类的模拟或监视。我们将分析使用非抽象方法测试抽象类的几种情况。
为了监视或模拟抽象类, 我们需要添加以下Maven依赖项:
- JUnit的
- Mockito
- PowerMock
<
dependency>
<
groupId>
junit<
/groupId>
<
artifactId>
junit<
/artifactId>
<
version>
4.12<
/version>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.mockito<
/groupId>
<
artifactId>
mockito-all<
/artifactId>
<
version>
1.10.19<
/version>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.powermock<
/groupId>
<
artifactId>
powermock-module-junit4<
/artifactId>
<
version>
1.7.4<
/version>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.powermock<
/groupId>
<
artifactId>
powermock-api-mockito<
/artifactId>
<
version>
1.7.0<
/version>
<
scope>
test<
/scope>
<
/dependency>
仅在使用PowerMock的测试中才需要PowerMock依赖项。
模拟抽象类的例子
1.使用Mockito.spy()监视抽象类
在此示例中, 我们将使用Mockito.spy()方法监视抽象类。 Mockito.spy()方法用于创建抽象类的间谍实例。
步骤1:创建一个名为Abstract1_class的抽象类, 其中包含抽象方法和非抽象方法。
Abstract1_class.java
public abstract class Abstract1_class { public abstract int newAbstractmethod();
public String methodUnderTest() {
return "one" ;
}
}
步骤2:创建一个名为Abstract1Test的JUnit测试用例。它包含抽象类的间谍实例。
Abstract1Test.java
import static org.junit.Assert.*;
import org.junit.Test;
import org.mockito.Mockito;
import junit.framework.Assert;
public class Abstract1Test { @Test
public void testing_usingSpy() {
Abstract1_class abstclas = Mockito.spy(Abstract1_class.class);
String res = abstclas.methodUnderTest();
Assert.assertEquals("one", res);
}
}
输出如下
以下输出显示测试已成功运行。
文章图片
使用Mockito.spy()方法的缺点是, 它将在创建间谍实例的过程中调用抽象类的构造函数。在大多数情况下, 构造函数使用外部依赖关系, 这可能会妨碍我们执行单元测试。这些外部依赖关系通常称为测试障碍。这是使用Mockito.mock()方法模拟抽象类的原因。
2.使用Mockito.mock()模拟抽象类
在此示例中, 我们将使用Mockito.mock()方法模拟抽象类。
通常, 模拟用于创建类的克隆或伪对象。换句话说, 它使类脱离了其逻辑或算法。创建的模拟实例在方法内部不包含代码(逻辑)。
步骤1:创建一个名为Abstract_Class的抽象类, 其中包含抽象方法和非抽象方法。
Abstract_Class.java
public abstract class Abstract_Class { public String sayMock() {
return "Hii.. " + getName() + symbol() ;
}
private String symbol() {
return "!!";
}
protected abstract String getName();
}
步骤2:创建一个名为AbstractTestClass的JUnit测试用例, 以模拟抽象类。
AbstractTestClass.java
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;
public class AbstractTestClass { @Test
public void test_AbstractClasses() {Abstract_Class ac = mock(Abstract_Class.class);
when(ac.sayMock()).thenCallRealMethod();
when(ac.getName()).thenReturn("Jyotika");
assertEquals("Hii.. Jyotika!!", ac.sayMock());
}
}
在上面的代码中, ac是使用Mockito.mock()方法创建的模拟实例。
输出如下
以下输出显示使用Mockito成功运行了测试。
文章图片
上面的方法不是最好的, 但是可以使用。建议使用下一种方法, 因为它使用PowerMock, 并且可以控制抽象类中定义的私有方法。
3.使用PowerMock模拟抽象类
在下面的示例中, 我们将使用PowerMockito.mock()方法来模拟抽象类。使用PowerMock代替Mockito.mock()是更好的方法, 因为它可以控制私有方法和静态方法。
步骤1:创建一个名为Abstract_class的抽象类, 其中包含抽象方法和非抽象方法。
Abstract_class.java
public abstract class Abstract_Class { public abstract int myAbstractMethod();
public String sayMock() {
return getName() + "13" ;
}
private String getName() {
return "Jyotika";
}
}
步骤2:创建一个名为AbstractTestClass的JUnit测试用例以进行测试。
AbstractTestClass.java
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest( Abstract_Class.class)
public class AbstractTestClass { @Test
public void test_AbstractClassesusing_PowerMock() throws Exception {
// given
Abstract_Class ac = PowerMockito.mock(Abstract_Class.class);
PowerMockito.doCallRealMethod().when(ac).sayMock();
PowerMockito.doReturn("Sharma").when(ac , "getName");
//when
String newstring = ac.sayMock();
//then
assertEquals("Sharma13", newstring);
System.out.println(newstring);
}
}
在这里, 我们要求PowerMock对私有方法的返回值进行存根, 以便我们可以在没有任何测试障碍的情况下测试sayMock()方法。仅Mockito不能使用此方法, 这就是为什么我们将PowerMock与Mockito一起使用的原因。
输出如下
【Mockito监视或模拟抽象类】以下输出显示使用PowerMock和Mockito成功运行了测试。
文章图片
推荐阅读
- Puppet教程入门介绍
- PowerMock模拟对象
- Mockito与EasyMock有什么区别()
- Hamcrest Matchers介绍和用法
- 行为驱动开发(BDD)
- 参数捕获器(ArgumentCaptor)
- Mockito参数匹配器
- 读取 Android 设备内核日志的方法
- etherlime-3-Etherlime Library API-Deployed Contract Wrapper