我应该如何模拟我试图测试的对象中的单个方法?

时间:2015-07-13 17:25:32

标签: java junit mockito

我遇到了一个问题,我正在测试几乎我想要测试的每个方法中的一个类,每个方法所做的第一件事就是调用这个特定的方法。所有这些其他方法调用一次的方法需要很长时间才能执行。我不想每次运行测试时都要等待这个,这真的是浪费时间。

我尝试使用Mocktio来@Spy方法,但我遇到了问题,因为很长的方法并没有返回任何东西。有人可以提出一个很好的方法来模拟我试图测试的类中的单个方法吗?

示例:

public class myClass {

    public void methodOne() {
        reallyLongMethod();
        // More code
    }

    public void methodTwo() {
        reallyLongMethod();
        // More code
    }

    .
    .
    .

    public void methodN() {
        reallyLongMethod();
        // More code
    }

    public void reallyLongMethod() {

    }
}

这是我要测试的课程。我想测试所有'方法X()'方法。但是,我不想在任何时候运行真正的LongMethod。

那么,有没有办法使用Mockito' Spy'去掉reallyLongMethod()?即使它没有任何东西?

1 个答案:

答案 0 :(得分:4)

您可以将间谍与doNothing()一起使用,但请确保在测试期间使用间谍。 Mockito间谍复制原件,而不是委托给它。

@RunWith(MockitoJUnitRunner.class)
public class YourTest {
  // Option 1:
  // @Spy MyClass myClass = new MyClass();

  // Option 2 (see @Before method)
  MyClass myClass;

  @Before public void ignoreReallyLongMethod() {
    myClass = spy(new MyClass());  // discard original
    doNothing().when(myClass).reallyLongMethod();
  }

  @Test public void methodOneWorks() {
    myClass.methodOne();  // you're using the spy here
    assertEquals(42, myClass.getFoo());
  }
}

虽然这确实引起了代码味道,但不会模拟或存根测试中的类,只要您小心测试方法行为(methodOne)而不是存根行为(reallyLongMethod)你会很高兴。如果您确实要测试reallyLongMethod,则需要使用其他对象实例,否则您将单独“测试”doNothing()调用。请记住,如果reallyLongMethod和您的其他方法有任何负面互动,这些测试都不会告诉您。

顺便说一下,你也可以在不使用Mockito的情况下做同样的事情,这可能会让你更清楚你的嘲讽是什么或不做什么:

@RunWith(JUnit4.class)
public class YourTest {
  MyClass myClass;

  @Before public void createMyClass() {
    myClass = new MyClass() {  // create an anonymous inner class
      @Override public void reallyLongMethod() {}  // that does nothing here
    };
  }
}