我是Jmockit的新手,我有一个场景来模拟正在使用的List 商业逻辑。当我使用下面的实现时,我得到 java.lang.IllegalStateException:此时缺少对mocked类型的调用;请确保仅在声明合适的模拟字段或参数
之后才会出现此类调用请在下面找到我的实施。
package com.example.logic;
import java.util.ArrayList;
import java.util.List;
public class EmployeeDao {
public boolean validate() {
List<String> list = getList();
if (list.size() > 0) {
return true;
}
return false;
}
public List<String> getList() {
//actual logic for getting the data
List<String> list = new ArrayList<>();
return list;
}
}
package com.example.test;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.example.logic.EmployeeDao;
import mockit.NonStrictExpectations;
public class EmployeeDaoTest {
@Test
public void testEmployeeDaoTest() {
EmployeeDao employeeDao = new EmployeeDao();
new NonStrictExpectations() {
{
employeeDao.getList();
// returns("A", "B");
//times = 1;
result = getMockList();
//returns("A", "B");
}
};
assertTrue(employeeDao.validate());
}
private List<String> getMockList() {
List<String> list = new ArrayList<>();
list.add("A");
return list;
}
}
当我运行上面的Test类时,我得到了以下错误。但是,如果正在使用@Mocked注释,那么会实现EmployeeDao,那么我只会得到 断言错误
@Mocked
EmployeeDao employeeDao;
经过一些研究后,我通过另一种方式使用MockUp来模拟该方法。但由于某些原因,我不想使用。这会有所帮助 如果可以用我编写的上述方法来解决这个问题。只是想知道上述实现的错误。
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter
at com.example.test.EmployeeDaoTest$1.<init>(EmployeeDaoTest.java:23)
at com.example.test.EmployeeDaoTest.testEmployeeDaoTest(EmployeeDaoTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
答案 0 :(得分:2)
你遇到的问题是你需要使用partial mocking(因为你正在测试一个类并模拟它的一个方法)。
这样做的方式是这样的:
@Test
public void testEmployeeDaoTest() {
EmployeeDao employeeDao = new EmployeeDao();
new NonStrictExpectations(employeeDao) {
{
employeeDao.getList();
// returns("A", "B");
//times = 1;
result = getMockList();
//returns("A", "B");
}
};
assertTrue(employeeDao.validate());
}
答案 1 :(得分:0)
两件事:
NonStrictExpectations
类。目前
版本是v1.39。您可能希望升级并获得所有最新修补程序和增强功能的好处EmployeeDao
的每个实例,这实际上意味着你不会测试任何东西。中间地带是部分模拟,它只会模拟类或实例的select方法。我修改了示例以使用Expectations
minTimes = 0
实例(使其成为可选项),并简化了IMHO的结果,使其更具可读性:
@Test
public void testEmployeeDaoTest() {
EmployeeDao employeeDao = new EmployeeDao();
new Expectations(EmployeeDao.class) {
{
employeeDao.getList();
result = Collections.singletonList("A");
minTimes = 0;
}
};
assertTrue(employeeDao.validate());
}
答案 2 :(得分:0)
创建getlist()方法的模型并根据测试用例返回所需的对象
new MockUp<EmployeeDao>() {
@Mock
List<String> getList() // no access modifier required
{
return requiredListOutput;
}
}
new Expectations() {
{
};
assertTrue(employeeDao.validate());//required assertions