2013-07-16 28 views
6

私は次のようなクラスを持っています。JMockitで私的静的フィールドをモックしますか?

class ClassA { 
    private static File myDir; 

    // myDir is created at some stage 

    private static String findFile(final String fileName) { 
     for (final String actualBackupFileName : myDir.list()) { 
      if (actualBackupFileName.startsWith(removeExtensionFrom(backupFile))) { 
       return actualBackupFileName; 
      } 
     } 
    } 
} 

だから、基本的に、私はリスト()がそれに呼び出されたとき、それは私が私のテストクラスで定義された文字列のリストを返すようにFileクラスをモックすることにより、このクラスをテストしたいです。

私は次のようなことがありますが、それは分からないことでしょう。私は間違っていることを明らかにしています。私はJMockitを初めて使用しています。

@Mocked("list") File myDir; 

@Test 
    public void testClassA() { 
    final String[] files = {"file1-bla.txt"}; 

    new NonStrictExpectations() {{ 
     new File(anyString).list(); 
     returns(files); 
    }}; 

    String returnedFileName = Deencapsulation.invoke(ClassA.class, "findFile","file1.txt"); 

    // assert returnedFileName is equal to "file1-bla.txt" 
    } 

上記のテストを実行しているとき、私はにClassAでmyDirにフィールドのNullPointerExceptionが取得する - ので、その適切嘲笑得ていないように見えますか?

答えて

10

JMockit(またはその他のモックツール)モックフィールドや変数が、それはこれらのタイプのインスタンスを取得種類(クラス、インタフェースなど)を皮肉っていませんがテスト中のコードの中に格納されているものは関係ありません。

ClassA用例試験

@Test 
public void testClassA(@Mocked File myDir) 
{ 
    new Expectations() {{ myDir.list(); result = "file1-bla.txt"; }}; 

    String returnedFileName = new ClassA().publicMethodThatCallsFindFile("file1.txt"); 

    assertEquals("file1-bla.txt", returnedFileName); 
} 

上記に取り組むべきです。直接privateメソッドをテストする(またはprivateフィールドにアクセスする)ことは悪い習慣とみなされるので、ここではそれを避けました。また、Fileクラスを嘲笑することを避けるのが最善です。代わりに、あなたのpublicメソッドだけをテストし、ファイルシステムを嘲笑する代わりに実際のファイルを使用してください。

+0

あなたの助けを借りてくれてありがとう、Rogerio、これはあなたのコードに小さな変更を加えたものです。@Mocked File myDirを@Mocked(methods = {"list"})に変更する必要がありました。 Deencapsualtion.invokeコールでは、ある時点で実際のFileオブジェクトが必要になる可能性があり、すべてのメソッドを嘲笑して何かを妨害していたように思えるかもしれません。私は新しいユーザーですので、投票できません - そうでなければ私はそうです! – user2586917

+1

素晴らしい! JMockitの古いバージョンでは、 'File'を嘲ることは予期しない失敗を引き起こす可能性があります。あなたの変更に合わせて答えを編集しました。 –

+0

@Rogério、mockオブジェクト( 'myDir')を作成する上記の方法は参照が' null'になり、 'myDir.list()'が 'NPE'で失敗する原因となります。どんな考え? – mystarrocks

0

この試してみる:

new Expectations {{ 
    invoke(File.class, "list", null, null); 
    returns(files); 
}} 
+1

おかげで、しかし、ドキュメントが呼び出すと言うの静的メソッドを呼び出すためである - ファイルのリスト()は静的ではありません - 動作するようには思えません。 – user2586917

7

DeencapsulationクラスのsetFieldメソッドを使用できます。下の例に注意してください。

Deencapsulation.setField(ClassA, "File", your_desired_value); 
関連する問題