4

テストしているクラス内のオブジェクトのメソッドをモックしようとしています。

例えば

class ClassToTest {
   public doSomething () {
       SomeObject a = new SomeObject ();
       a.doSomethingElse ();
   }
}

変数「a」のメソッドをモックする方法はありますか?テスト中はdoSomethingElseに何もしないようにしたいと思います。私は現在Mockitoを使用していますが、あらゆるモックフレームワークを利用できます。

ありがとう

4

6 に答える 6

2

もちろん、いくつかのリファクタリングを使用すると、次のことが可能になります。

class SomeObject {
    public void doSomethingElse()
    {

    }
}

class ClassToTest
{
    private final SomeObject someObject;

    public void doSomething()
    {
        someObject.doSomethingElse();
    }

    public ClassToTest(SomeObject someObject)
    {
        this.someObject = someObject;
    }
}

class Test {
    @Test
    public void testDoSomething()
    {
        SomeObject someObject = Mockito.mock(SomeObject.class);
        new ClassToTest(someObject).doSomething();
        Mockito.verify(someObject, Mockito.atLeastOnce()).doSomethingElse();
    }
}
于 2010-10-14T13:02:49.663 に答える
2

あなたの場合のように、ローカル変数として宣言されている場合、参照「a」をモックすることはできません。たとえば、doSomethingメソッドのパラメーターとして、SomeObjectに依存関係を挿入することを検討できます。そうすれば、代わりにテストにSomeObjectのモックを挿入できます。

依存性注入の利点の1つは、テスト容易性の向上です。

于 2010-10-14T12:56:53.853 に答える
2

はい、次のJMockitテストで示されるように、方法があります。

public void testDoSomething(final SomeObject mock)
{
    new ClassToTest().doSomething();

    new Verifications() {{ mock.doSomethingElse(); }};
}

ラッパーやDIなどを使用するために、テスト対象のコードをリファクタリングする必要はありません。嘲笑する必要があるものは何でも嘲笑するだけです。

于 2011-02-15T12:26:46.343 に答える
1

EasyMock 2.5以前ではEasyMockクラス拡張機能を使用できると思いますが、3.0に含まれているようです。何をしようとしているのかについては、前のページのこの部分を参照してください。とはいえ、私は個人的にそうしようとはしていないので、どれだけうまくいくかわかりません。

于 2010-10-14T12:59:23.363 に答える
0

呼び出しごとに新しいインスタンスが必要な場合は、次の方法でリファクタリングすることをお勧めします。

class ClassToTest {
   public doSomething () {
      SomeObject a = getInstance();
      a.doSomethingElse ();
   }
   protected SomeObject getInstance() {
      return new SomeObject();
   }
}

次に、ClassToTestを拡張するテストクラスを作成し、getInstance()メソッドをオーバーライドして、モックオブジェクトを提供します。

もちろん、これはgetInstance()メソッドの公開に問題がない場合にのみ実行可能であるため、クラスがパブリックAPIの一部である場合はお勧めしません。この場合、依存性注入を使用してファクトリクラスを提供することを検討してください。

于 2010-10-14T13:14:32.587 に答える
0
class ClassToTest {
    private SomethingElseInterface somethingElseDoer ;

    public ClassToTest(SomethingElseInterface somethingElseDoer) {
        this.somethingElseDoer = somethingElseDoer;
    }

    public doSomething () {
        somethingElseDoer.doSomethingElse();
    }
}

そして、あなたがそれを使う場所:

SomethingElseInterface somethingElseDoer = ...; // in a test, this is where you mock it
ClassToTest foo = new ClassToTest(somethingElseDoer); // inject through constructor
foo.doSomething();
于 2010-10-14T13:36:18.610 に答える