2016-12-02 19 views
-1

使用したJMockitのバージョン:1.21 私はこのようなインターフェースを持っています。 TestInterface:Jmockit:インターフェースフィールドの呼び出し方法を確認してください。

public interface TestInterface { 
    boolean callMethod(); 
} 

A TestClassを、フィールドがそのインターフェイス TestClassをのインスタンスである必要があり:

public class TestClass { 
    private final TestInterface inner = new TestInterface() { 
     @Override 
     public boolean callMethod() { 
      subMethod(); 
      return false; 
     } 
    }; 
     public void subMethod() { System.out.println("Sub method"); 
    }; 
} 

は、私は偽物interfaceinこのチュートリアルによってメソッドを呼び出すことを検証してみてください。 http://jmockit.org/tutorial/Faking.html#interfacesd

試験方法。

public class TestInterfaceTest { 
    TestClass sut; 
    @Before 
    public void setUp() { 
     sut = Deencapsulation.newInstance(TestClass.class); 
    } 
    @Test 
    public void mockAllClassesImplementingAnInterface() { 

     TestInterface testInterface = new MockUp<TestInterface>() { 
      @Mock 
      public boolean callMethod(Invocation inv) { 
       inv.proceed(); // throw exception here -> Will my expected method be called here? 
       return true; 
      } 
     }.getMockInstance(); 

     Deencapsulation.setField(sut, "INTER", testInterface); 

     new NonStrictExpectations() { 
      { 
       Deencapsulation.invoke(sut, "subMethod"); 
      } 
     }; 

     Boolean result = Deencapsulation.invoke(Deencapsulation.getField(sut, "INTER"), "callMethod"); 

     assertTrue(result); 

     new Verifications() { 
      { 
       Deencapsulation.invoke(sut, "subMethod"); times = 1; 
      } 
     }; 
    } 
} 

java.lang.IllegalArgumentExceptionが:君たちは気にしない場合は "$ Impl_TestInterfaceはndroid.examples.helloandroid"

を発見した名前 ではありませんクラス、あなたが私に教えてください可能性がありこれを解決する方法どうもありがとう。

+0

私はあなたの「サンプルコード」(* *あなたの[MCVE](http://stackoverflow.com/help/mcve)をコンパイルし、実行していることを確認してください!)でのエラーを修正すると、すべてが正常に働いて、このエラーは表示されませんでした。あなたはあなたの問題を詳述しなければならないでしょう。 – dcsohl

+0

あなたの確認のために@dcsohlに感謝します。現在、私はバージョン1.21で実装しています、それはそのエラーをスローします。 バージョン1.21だけでなく、バ​​ージョン1.29でも例外がスローされます。 :D エラーを再現するためにどのバージョンを使用しましたか? –

+0

Androidスタジオでテストします:D –

答えて

2

あなたの問題は、この問題の再評価において、inv.proceed()という行にあるようです。その回線は、インターフェイスのMockupに入れることはできません。

Invocation.proceed()は、MockUpの実装を実際のコードに進める場合に使用します。しかし、あなたはインターフェイスを模倣しているので、は実際のコードはありません。 TestClassの実装にはインターフェイスの匿名実装がありますが、MockUpにはその匿名クラスは何も分かっていないため、そこにあると思うかもしれません。それはあなたの匿名の実装ではなく、インターフェースのモックアップをしています。

この行を削除した場合、Invocation.proceed()に電話すると、エラーがなくなることがわかります。

+0

お世話になり誠にありがとうございます。だから匿名の方法を検証することはできません。 –

+0

私はそれを言っていませんでした。私はあなたがそれに進まないと言いました。あなたはそれを嘲笑し、それが呼び出されていることを確認することができます。 – dcsohl

+0

私は、そのクラスに処理できず、subMehodが実際のメソッドの中で呼び出されたことを確認できませんでした。そうですか?親切なサポートに感謝します。 –

-1

@dcsohlのガイダンスに基づいています。以下のコードは私のために働く。

@Test 
    public void mockAllClassesImplementingAnInterface() { 
     // Partial mocking 
     new NonStrictExpectations(sut) { 
      { 
       sut.subMethod(); 
      } 
     }; 

     // Actual invocation 
     Deencapsulation.invoke(Deencapsulation.getField(sut, "inner"), "callMethod"); 
     // Verify 
     new Verifications() { 
      { 
       Deencapsulation.invoke(sut, "subMethod"); 
       times = 1; 
      } 
     }; 
    } 
+0

私はこのテストに間違いがあるのではないかと心配しています(1つは 'Deencapsulation.invoke'を使用しないでください)。しかし、もっと重要なのは、すべてのテスト(テスト+テストするコード)は意味がないようです...適切なテストは、いくつかの有意義で外部的に観察可能な動作を検証することになっています。 –

関連する問題