您好我有以下课程
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编写测试用例,因为我需要在getData()
中模拟DataAccessLayer<T>
方法
是否可以使用jmockit
模拟模板(通用)类?
答案 0 :(得分:1)
在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
构造函数的结果是我们在测试的后续步骤中使用的结果。 Expectations
对象上@Mocked
的默认行为是记录对该类的任何对象的期望;这就是我们如何确定它正在使用的我们的对象。 (通常我不会为此烦恼,但在使用new
时,我希望确定。)
最后,我省略了在这种情况下我可能会做的其他一些事情,例如使用Verifications
块等等。只是尽量做到尽可能简单。
享受!
答案 1 :(得分:1)
泛型类可以像非泛型类一样进行模拟:
start end id
# 326.019 340.133 1
# 451.142 469.626 2
# 597.985 617.004 3
# 778.896 797.714 4
# 1014.590 1038.280 5
df = structure(list(start = c(326.019, 451.142, 597.985, 778.896,
1014.59), end = c(340.133, 469.626, 617.004, 797.714, 1038.28
), id = 1:5), .Names = c("start", "end", "id"), row.names = c(NA,
-5L), class = "data.frame")
答案 2 :(得分:0)
(我只能真正回答Mockito,因为这是我最熟悉的;但同样的原则应适用于其他模拟框架。)
首先,您需要能够将>>> any((ts - mavg).dropna().abs() > 1e-14)
False
注入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();
}
}
创建的DataAccessLayer<UtilClass>
的静态耦合。
现在,您可以通过创建非泛型子类来创建new
的模拟实例:
DataAccessLayer<UtilClass>
然后创建一个模拟实例:
class UtilClassDataAccessLayer extends DataAccessLayer<UtilClass> {}
现在,您可以根据需要配置此模拟,并将其传递到DataAccessLayer<UtilClass> mocked = mock(UtilClassDataAccessLayer.class);
:
ServiceLayer