【问题标题】:Verify that a private method was NOT executed JMockit验证未执行私有方法 JMockit
【发布时间】:2016-08-05 20:50:25
【问题描述】:

我已经四处寻找这个问题,但没有找到我真正需要的东西。我学到了更多关于 JMockit 和 mocking 的知识。哪个好。似乎每个人都想知道如何确保某些事情已经执行。我想学相反的东西。

好的 - 我正在编写一个测试来检查公共方法中不那么愉快的路径。正在测试的方法是void 所以我真的不能assert 结果。 我想做的是验证这个测试用例中没有执行一个方法。

例如:

class ClassToTest {
  private void method(String arg){}

  public void publicMethod(String arg0, String arg1){
    if(false){
      //this method should never get called.
      method(arg0);
    }
  }
}

class TestingClass{
  @Tested
  private ClassToTest classToTest = new ClassToTest();

  @Test
  public void testCheckingIfPrivateMethodWasCalled(){
    classToTest.publicMethod("string1", "string2");

    new Verifications() {
      {
        //At this point I am trying something like
        Deencapsulation.invoke(classToTest, "method", "string1");
        times = 0; //Also tried maxTimes = 0;
        //Through debug it looks like the invoke is doing what it's named...
        //invoking the private method, I don't want to invoke.
        //How do I check that ClassToTest#method was not called?
      }
    }
  }
}

我得到的测试用例结果是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。哪个在times = 0;线上。

我知道invoke 正在执行私有方法。我正在摸不着头脑,试图弄清楚如何“检查”所述方法是否被调用而不调用/执行它。

谢谢。

【问题讨论】:

  • 测试您的应用程序的状态。如果您的私有方法的调用很重要,它应该在某处影响状态,并且您应该能够对其进行测试。除此之外,也许考虑为方法提供默认可见性(又名包保护),以便您的测试可以验证它。 (这是假设您的测试与您正在测试的类位于同一个包中,这是一个合理的假设。)
  • 从不模拟 private 方法,没有充分的理由这样做。想一想:关注质量的开发人员可以随时创建或内联私有方法。您真的希望在通过保留功能的重构改进生产代码的同时修改工作测试吗?即使您不关心这一点,也要考虑团队中或将来的其他开发人员可能会这样做。

标签: java unit-testing jmockit


【解决方案1】:

一种方法是使用 faking 的 MockUp API:

import static org.junit.Assert.assertFalse;

import org.junit.Test;

import mockit.Mock;
import mockit.MockUp;
import mockit.Tested;

public class TestingClass {

    @Tested
    private ClassToTest classToTest = new ClassToTest();

    @Test
    public void testCheckingIfPrivateMethodWasCalled() {
        PrivateMethodCheckMockUp mockUp = new PrivateMethodCheckMockUp() {
            @Mock
            private void method(String arg) {
                calledPrivate = true;
            }
        };

        classToTest.publicMethod("string1", "string2");

        assertFalse(mockUp.calledPrivate);
    }

    class PrivateMethodCheckMockUp extends MockUp<ClassToTest> {
        boolean calledPrivate = false;

        @Mock
        private void method(String arg) {
            calledPrivate = true;
        }
    }
}

【讨论】:

  • 所以你是在模拟一个类的实例然后模拟那个类的方法?你嘲笑PrivateMethodCheckMockUp#method 两次是什么?
  • 实际上ClassToTest 只被模拟了一次,@Tested 不会创建模拟,“JMockit 可以通过自动实例化这个类来提供帮助,并且可以选择注入相关的模拟依赖项。这就是@Tested注释是为了。”
  • 然后我使用MockUp API 模拟它的私有方法,并使用一个标志来知道它是否被调用(也许Assert.fail() 就足够了)。
猜你喜欢
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多