2016-12-29 14 views
0

からデータを読み込み、処理するメソッド:テスト私は次のコードを持っているファイル

public class FolderServiceImpl implements FolderService { 

    private static final Logger L = LoggerFactory.getLogger(FolderServiceImpl.class); 

    public int getStatus(String folderPath) { 
     int status = 0; 
     File folderStatusFile = new File(folderPath, ".folderstatus"); 
     if (folderStatusFile.exists()) { 
      BufferedReader br = null; 
      try { 
       br = new BufferedReader(new FileReader(folderStatusFile)); 
       String line = br.readLine(); 
       status = Integer.parseInt(line); 
      } catch (Exception e) { 
       L.error("can't read file " + folderStatusFile.getAbsolutePath(), e); 
       status = 4; 
      } finally { 
       if (br != null) { 
        try { 
         br.close(); 
        } catch (IOException e) { 
         L.warn("could not close reader ", e); 
        } 
       } 
      } 

     } else { 
      status = 3; 
     } 
     return status; 
    } 
} 

を、私はすべてのケースのために実際のファイルを作成せずに、このメソッドをテストしたいです。私はJava 1.7、JUnit 4、Mockito、PowerMockitoのいずれかを使用するべきです。

これを行う方法に関するアイデアはありますか?

私は、データソースを嘲笑したり、単にメソッドの入力を変更することについて話しています。

私のテストでは、このようなものになります。

`@Rule パブリックTemporaryFolderフォルダ=新しいTemporaryFolderを();

@RunWith(PowerMockRunner.class) 
@PrepareForTest(tests.class) 
public class test { 

@Test 
public void test() throws Exception { 
    File fileMock = Mockito.mock(File.class); 
    PowerMockito.whenNew(File.class).withArguments(Mockito.anyString(), Mockito.anyString()).thenReturn(fileMock); 
    FolderServiceImpl sut = new FolderServiceImpl sut(); 
    Mockito.when(fileMock.exists()).thenReturn(true); 
    sut.getStatus(""); 

// Your verifications.. 
} 
} 

PowermockがあなたのクラスのメソッドのgetStatusで作成されたFileオブジェクトを模擬します:

private FolderServiceImpl serviceToTest = new FolderServiceImpl(); 

private String folderPath; 

@Before 
public void setUp() { 
    folderPath = folder.getRoot().getAbsolutePath(); 
    try { 
     folder.newFile(".folderstatus"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

@Test 
public void shouldReturnFolderStatus3WhenFolderStatusIsNotFound() { 
    // given 
    deleteFolderStatusFile(); 

    // actual 
    int status = serviceToTest.getFolderStatus(folderPath); 

    // expected 
    assertEquals(3, status); 
} 

@Test 
public void shouldReturnFolderStatus4WhenTheStatusIsUnreadable() { 
    // given 
    writeStatusToTestFile("Test"); 

    // actual 
    int status = serviceToTest.getFolderStatus(folderPath); 

    // expected 
    assertEquals(4, status); 
} 

@Test 
public void shouldReturnFolderStatusInTheFile() { 
    // given 
    writeStatusToTestFile("1"); 

    // actual 
    int status = serviceToTest.getFolderStatus(folderPath); 

    // expected 
    assertEquals(1, status); 

} 

private void writeStatusToTestFile(String status) { 
    Path file = Paths.get(folder.getRoot().getAbsolutePath(), ".folderstatus"); 
    try { 
     Files.write(file, status.getBytes()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void deleteFolderStatusFile() { 
    Path file = Paths.get(folder.getRoot().getAbsolutePath(), ".folderstatus"); 
    try { 
     Files.delete(file); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
}` 

答えて

0

@BenHeidの答えが働くかもしれないが、私は」:私はMavenの持つ以下の二つのjarファイルが含まれているが、あなたはMavenを使用する必要はありません

EDIT

dは異なるアプローチに変わることを示唆している。

IMHO私がPowerMock(-ito)を使用したとき、それは悪いデザインに降伏したときです。 また、PowerMockソリューションは、カバレッジ測定用にインスツルメントされた後にアプリケーションバイトコードを変更するため、テストカバレッジツールを混乱させます。


だから私は好むアプローチはクリーンコードとOOPのルールに固執することです。

の1つです。

この場合、このメソッドは、作業するインフラストラクチャクラス(依存関係)を作成します。すなわち、FileReaderBufferedReaderです。

しかし、(直接的な)依存関係のインスタンス化は、ビジネスロジックを含むクラスの責任ではありません。

ので、私は別のクラスに出ているコードをリファクタリングすることをお勧めしたい:

class ReaderFactory { 
    public BufferedReader createFor(File file) throws FileNotFoundException { 
     return new BufferedReader(new FileReader(file)); 
    } 
} 

あなたのクラスは、これに変更します

class FolderServiceImpl { 
    private static final Logger L = LoggerFactory.getLogger(FolderServiceImpl.class); 
    private final ReaderFactory readerFactory; 

    FolderServiceImpl(ReaderFactory readerFactory) { 
     this.readerFactory = readerFactory; 
    } 

    public int getStatus(String folderPath) { 
     int status = 0; 
     File folderStatusFile = new File(folderPath, ".folderstatus"); 
     // try "with resource" takes care of closing the reader 
     try (BufferedReader br = readerFactory.createFor(folderStatusFile);) { 
      String line = br.readLine(); 
      status = Integer.parseInt(line); 
     } catch (IOException e) { 
      status = 3; 
     } catch (Exception e) { 
      L.error("can't read file " + folderStatusFile.getAbsolutePath(), e); 
      status = 4; 
     } 
     return status; 
    } 
} 

そして、あなたのテストはこのようになります:

public class FolderServiceImplTest { 

    private static final String ANY_FILE_NAME = ""; 

    @Rule 
    public MockitoRule mockitoRule = MockitoJUnit.rule(); 

    @Rule 
    public ExpectedException thrown = ExpectedException.none(); 

    @Mock 
    private ReaderFactory readerFactory; 

    @InjectMocks 
    FolderServiceImpl sut; 

    @Test 
    public void getStatus_FileNotExisting_returnStatus3() throws Exception { 
     // arrange 
     Mockito.doThrow(new FileNotFoundException("UnitTest")).when(readerFactory).createFor(Mockito.any(File.class)); 
     // act 
     int status = sut.getStatus(ANY_FILE_NAME); 
     // assert 
     Assert.assertThat("status",status,CoreMatchers.equalTo(3)); 
    } 

    @Test 
    public void getStatus_ValidFile_returnFileContentAsInt() throws Exception { 
     // arrange 
     BufferedReader bufferedReader = Mockito.mock(BufferedReader.class); 
     Mockito.doReturn(bufferedReader).when(readerFactory).createFor(Mockito.any(File.class)); 
     Mockito.doReturn("4711").when(bufferedReader).readLine(); 
     // act 
     int status = sut.getStatus(ANY_FILE_NAME); 
     // assert 
     Assert.assertThat("status",status,CoreMatchers.equalTo(4711)); 
    } 
} 
+0

'IOException'を' FileNotFoundException'で変更する必要があります。 – radumach

+0

@radumachはい、ありがとう、答えを変更しました。 –

0

あなたはこのようなものを使用する必要があります。 Mockito.whenを使用して、コード内のfolderStatusFile.exists()の戻り値が何であるかを言うことができます。 https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4/1.4.6https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito/1.4.9https://mvnrepository.com/artifact/org.mockito/mockito-all/1.10.19

+0

正しく実行されているかどうかはわかりませんが、このアプローチでは 'java.lang.IncompatibleClassChangeError:Found interfaクラスorg.powermock.api.mockito.internal.mockcreation.MockCreatorが期待されました。また、テストの考え方は、異なるシナリオ(ファイルプリセットなし、ファイルに書き込まれたintなし、ファイルに書き込まれたint)に応じて期待される結果を検証することです。 – radumach

+0

投稿を編集し、必要なjarを追加しました。おそらくあなたは間違ったものを含んでいます。 – BenHeid

+0

クラスパスに正確な依存関係があり、同じエラーが発生する – radumach

関連する問題