【问题标题】:Testing unimplemented method in abstract class在抽象类中测试未实现的方法
【发布时间】:2014-12-05 03:36:14
【问题描述】:

我有一个抽象类,比如AbstractClass,其中我有一个公共 void 方法 myMethod 没有实现。当我测试这个类时,我创建了一个匿名子类,我可以在其中实现myMethod,因为我认为合适。 在AbstractClass 中还有另一种方法,比如myImplementedMethod,它调用myMethod。我可以在匿名子类中放入myMethod,以便能够验证它是否已被调用?

编辑: 我正在使用 Mockito 进行模拟,我不适合使用其他框架。

public abstract class AbstractClass {
    public abstract void myMethod();

    public void myImplementedMethod() {
        myMethod();
}

public class AbstractClassTest {

    @Before
    public void setUp() {
        AbstractClass myClass = new AbstractClass() {

            @Override
            public void myMethod(){
                //What could I put here?
            }
        }
    }

    @Test
    public void testMyImplementedMethod() {
        myClass.myImplementedMethod();
        //check that myMethod is called.
    }
}

【问题讨论】:

  • 看看模拟框架。
  • 哦,我正在使用 Mockito
  • 然后检查以确保它被调用。如果子类不存在,它甚至无法编译。您具体要测试什么?
  • 如何检查它是否被调用?

标签: java junit abstract-class mockito


【解决方案1】:

如果 Mockito 的间谍对您有用,那就太好了。但是我不相信它会捕获内部方法调用。下面呢……

public class AbstractClassTest {

 boolean methodCalled = false;

@Before
public void setUp() {
    methodCalled = false;
    AbstractClass myClass = new AbstractClass() {

        @Override
        public void myMethod(){
            methodCalled = true;
        }
    }
}

@Test
public void testMyImplementedMethod() {
    assertFalse(methodCalled);
    myClass.myImplementedMethod();
    assertTrue(methodCalled);
}
}

【讨论】:

  • 好答案。这是我所希望的那种优雅,尤其是因为不鼓励使用 Mockito 的间谍。
【解决方案2】:

您可以在后代类上创建一个 spy 对象,调用已实现的方法,然后确保使用 verify 调用未实现的方法

AbstractClass myInstance= Mockito.spy(myClass);
myInstance.myImplementedMethod();
Mockito.verify(myInstance).myMethod();

【讨论】:

  • 我不相信间谍会起作用。我相信间谍只能验证对方法的外部调用而不是内部调用。
  • Spy 是用来模拟真实对象的,当然不会去做。真正起作用的是 verify(),它确保在 myInstance 上调用了 myMethod。老实说,我真的认为这是正确的方法,您的解决方案就像重新发明轮子。
  • 我也愿意接受您的解决方案。我还想知道为什么使用间谍(根据 Mockito 文档有点不鼓励)是合理的?
  • 我同意应该谨慎使用间谍的原因,但在某些情况下我认为它们是必要的,例如在使用第三方或遗留代码时。在您的情况下,您可以完全控制修改后代类(您甚至创建了一个仅用于测试的类),但在某些其他情况下可能并非如此
  • 你是对的。文档没有明确说明这一点,但尝试过它确实有效。
【解决方案3】:
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

public class AbstractClassTest {

    private AbstractClass myClass;

    @Before
    public void setUp() {
        AbstractClass instance = new AbstractClass() {
            @Override
            public void myMethod(){}
        }
        myClass = spy(instance);
    }

    @Test
    public void testMyImplementedMethod() {
        myClass.myImplementedMethod();
        verify(myClass).myMethod();
    }
}

【讨论】:

  • 我不相信间谍会起作用。我相信间谍只能验证对方法的外部调用,而不是内部调用。
  • 如果你不相信你可以检查它并阅读 doc for mockito。如果我的回答不正确。不要犹豫,投票给我的答案。
  • 你是对的。文档没有明确说明这一点,但尝试过它确实有效。
【解决方案4】:

你不能像这样使用反射api吗

YourClass.getClass().getMethod("myMethod").invoke(obj,args);  // pass the appropriate parameters

如果这引发了异常,那么您还没有实现该方法。 我自己没有尝试过,如果可行,请发表评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 2016-11-08
    • 2013-05-30
    相关资源
    最近更新 更多