0

単体テストをしようとしている非常に単純な方法があります。

public class MyAntTask extends org.apache.tools.ant.Task {
    public void execute() {
        fire();
    }

    public void fire() {
        // Do stuff
    }
}

execute()呼び出しが常に を呼び出すことを確認する単体テストを書きたいだけなfire()ので、次のように書きました。

@Test
public void executeCallsFire() {
    //GIVEN
    MyAntTask myTask = Mockito.mock(MyAntTask.class);

    // Configure the mock to throw an exception if the fire() method
    // is called.
    Mockito.doThrow(new RuntimeException("fired")).when(myTask).fire();

    // WHEN
    try {
        // Execute the execute() method.
        myTask.execute();

        // We should never get here; HOWEVER this is the fail() that's
        // being executed by JUnit and causing the test to fail.
        Assert.fail();
    }
    catch(Exception exc) {
        // THEN
        // The fire() method should have been called.
        if(!exc.getMessage().equals("fired"))
            Assert.fail();
    }
}

私は推測します (私は決して専門家ではありません) Mockito は通常、 を返すメソッドをモックできませんvoidが、これは回避策です。あなたは基本的に「特定のメソッドが実行されようとしているときはいつでもMock特定のものを返すオブジェクトで私のオブジェクトをラップする」と言います。そのため、MockitoRuntimeExceptionは実際に実行するのではなく、実行しようとしていることを確認し、代わりに例外をスローします。fire()実行確認済み?小切手。

渡す代わりに、最初Assert.fail()の への呼び出しのすぐ下で失敗しますmyTask.execute()

私の人生では、理由がわかりません。これは、JUnit が失敗のために私に提供している巨大なスタック トレースの最初の 10 行ほどです。

java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:92)
    at org.junit.Assert.fail(Assert.java:100)
    at net.myproj.ant.tasks.MyAntTaskUnitTest.executeCallsFire(MyAntTaskUnitTest.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)

StackOverflow の Mockito Gurus の皆さん、何か考えはありますか? 前もって感謝します!

4

2 に答える 2

6

myTask はモックであるため、実際のオブジェクトはまったく呼び出されません。実際のオブジェクトを呼び出すには、スパイを使用します。

verify を使用してメソッドが呼び出されたことをテストできるため、例外は必要ありません。

public void executeCallsFire() {
    MyAntTask myTask = Mockito.spy(new MyAntTask());

    myTask.execute();

    Mockito.verify(myTask).fire();
}

ただし、テストしているオブジェクトをモックしたいのは正しくないようです。通常は、代わりに別のオブジェクトへの呼び出しを検証するようにテストを設計することをお勧めします。

于 2012-09-16T02:10:17.387 に答える
0

私はここでより多くの設計上の問題を見ます:

  1. なぜ1行のメソッドが必要で、両方が公開されているのですか?
  2. モックは依存関係をシミュレートするためのものであり、テスト中のクラスのためのものではありません
  3. fire (非常に不明確な名前) を非公開にする場合。クラスのプライベートな動作をテストするべきではありません
于 2012-09-16T09:31:49.343 に答える