【问题标题】:Jmockit Missing invocation to mocked type at this pointJmockit 此时缺少对模拟类型的调用
【发布时间】:2018-02-08 04:31:54
【问题描述】:

我是 Jmockit 的新手,我有一个场景来模拟在 商业逻辑。当我使用下面的实现时,我得到 java.lang.IllegalStateException: Missing invocation to mocked type 此时;请确保此类调用仅在声明合适的模拟字段或参数之后出现

请在下面找到我的实现。

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;
    }
}

当我运行上面的测试类时,我得到了以下错误。但是,如果没有实例化 EmployeeDao,如果正在使用 @Mocked 注释,那么我只会得到 断言错误

@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)

【问题讨论】:

  • 只是好奇,这些答案是否能帮助您解决问题?

标签: junit mockito junit4 jmockit


【解决方案1】:

您遇到的问题是您需要使用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());
}

【讨论】:

    【解决方案2】:

    两件事:

    • NonStrictExpectations 类在 v1.25 中被删除。目前的 版本是 v1.39。您可能想要升级并受益于所有最新的修复和增强功能
    • 上面的第一个示例没有模拟任何内容,添加 @Mocked 注释会模拟 EmployeeDao 的每个实例,这实际上意味着您不会测试任何内容。

    中间立场是部分模拟,它只会模拟类或实例的选择方法。我修改了示例以使用带有minTimes = 0 的常规Expectations 实例(使其成为可选),并简化了恕我直言的结果,使测试更具可读性:

    @Test
    public void testEmployeeDaoTest() {
        EmployeeDao employeeDao = new EmployeeDao();
        new Expectations(EmployeeDao.class) {
            {
                employeeDao.getList();
                result = Collections.singletonList("A");
                minTimes = 0;
            }
    
        };
        assertTrue(employeeDao.validate());
    }
    

    【讨论】:

      【解决方案3】:

      创建 getlist() 方法的模型并根据测试用例返回所需的对象

       new MockUp<EmployeeDao>() {
      
                      @Mock
                     List<String> getList() // no access modifier required
                      {
                          return requiredListOutput;
                      }
          }
           new Expectations() {
      
                      {
      
                  };
      
           assertTrue(employeeDao.validate());//required assertions
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多