[英]Java Mockit : How to Mock a generic class method in JMockit
嗨,我有以下课程
public class DataAccessLayer<T> {
public T getData(Class<?> dataInfoType ,Integer id){
//Some logic here
}
}
public class ServiceLayer{
//this method has to be tested
public Integer testingMethode{
//The following line should be mocked
UtilClass info = new DataAccessLayer<UtilClass>().getData(UtilClass.class, 1);
retutn info.getSomeFieldWithIntegerValue();
}
}
我想为testingMethode编写测试用例,因为我需要在DataAccessLayer<T>
模拟getData()
方法
jmockit
是否可以模拟Template(Generic)类?
在JMockit中,实际上不需要在ServiceLayer
类中创建一个保持变量,也不需要为DataLayer
创建参数化的子类。 以下测试可以正常工作:
package com.example.dsohl;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mocked;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
@RunWith(JMockit.class)
public class TestTest {
public static class UtilClass {
public Integer foo() {
return 5;
}
}
public static class DataLayer<T> {
public T getItem(Class<T> clazz, int itemId) {
return null;
}
}
public static class ServiceLayer {
public Integer testMethod() {
UtilClass util = new DataLayer<UtilClass>().getItem(UtilClass.class, 1);
return util.foo();
}
}
// Test really begins here
@Tested ServiceLayer svc;
@Mocked DataLayer<UtilClass> data;
@Mocked UtilClass util;
@Test
public void testDateSubtraction() throws Exception {
new Expectations() {
{
new DataLayer<UtilClass>(); result = data;
onInstance(data).getItem(UtilClass.class, 1); result = util;
util.foo(); result = 37;
}
};
Integer i = svc.testMethod();
assertThat(i, equalTo(37));
}
}
一些注意事项:首先,我的DataLayer.getItem()
返回null,因此,如果注入失败,我们将得到NullPointerException
,很明显。 显然,您的代码无法像这样工作; 这只是说服您。
其次,我使用onInstance()
以便可以100%确定DataLayer
构造函数的结果是我们在测试的下一步中使用的结果。 @Mocked
对象上的Expectations
的默认行为是针对该类的任何对象记录期望; 这就是我们确定正在使用的是我们的对象的方式。 (通常我不必为此担心,但是在使用new
我想确定一下。)
最后,我省略了在这种情况下可能要做的其他事情,例如使用Verifications
块等。只是尝试尽可能简单明了。
请享用!
通用类可以像非通用类一样进行模拟:
@Test
public void example(@Mocked final DataAccessLayer<UtilClass> mock)
{
final UtilClass data = new UtilClass(123);
new Expectations() {{ mock.getData(UtilClass.class, 1); result = data; }};
int result = new ServiceLayer().testingMethode();
assertEquals(123, result);
}
(我只能真正回答Mockito,因为这是我最熟悉的;但是相同的原理应该适用于其他模拟框架)。
首先,您需要能够将DataAccessLayer<UtilClass>
注入ServiceLayer
,例如
class ServiceLayer {
private final DataAccessLayer<UtilClass> dal;
ServiceLayer(DataAccessLayer<UtilClass> dal) {
this.dal = dal;
}
public Integer testingMethode() {
UtilClass info = dal.getData(UtilClass.class, 1);
return info.getSomeFieldWithIntegerValue();
}
}
这打破了与使用new
创建的DataAccessLayer<UtilClass>
的静态耦合。
现在,您可以通过创建一个非通用子类来创建DataAccessLayer<UtilClass>
的DataAccessLayer<UtilClass>
实例:
class UtilClassDataAccessLayer extends DataAccessLayer<UtilClass> {}
然后创建一个模拟实例:
DataAccessLayer<UtilClass> mocked = mock(UtilClassDataAccessLayer.class);
现在,您可以根据需要配置此模拟,并将其传递给ServiceLayer
:
ServiceLayer serviceLayer = new ServiceLayer(mocked);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.