2017-02-15 7 views
2

私は、このメソッドをテストしようとしている:ここでvoidメソッドがMockitoとcatch-exceptionを使用して例外をスローすることをアサートする方法は?

public void deleteCurrentlyLoggedInUser(Principal principal) { 
    if (findLoggedInUser(principal) == null) { 
     throw new UserAlreadyDeletedException(); 
    } 
    userRepository.delete(findLoggedInUser(principal)); 
} 

がfindLoggedInUserです:

User findLoggedInUser(Principal principal) { 
    return userRepository.findByUsername(principal.getName()); 
} 

そしてここでは、これまでのところ、私のテストです:

@Test 
public void shouldThrowExceptionWhenUserNotFound() { 
    // given 
    when(sut.findLoggedInUser(principalStub)).thenReturn(null); 

    // when 
    sut.deleteCurrentlyLoggedInUser(principalStub); 

    // then 
    catchException 
    verify(userRepositoryMock, never()).delete(any(User.class)); 
} 

それでは、どのように私は例外をキャッチしますここでcatch-exceptionを使用していますか?私がテストしているメソッドはvoidを返し、例外が見つかったと主張する方法を見つけることができないようです。

編集:私は@Test(expected = UserAlreadyDeletedException.class)を使用することができると知っていますが、これははるかに優れており、@Testで期待される使用法は非常に妥当ではないため、私のプロジェクト全体をcatch例外に切り替える必要があります。

+0

'expected = SomeException.class'は使用しないでください。メソッド内のどの式が実際に例外をスローするかについてのコントロールや可視性はありません。その上に 'try/catch'を使用することが望ましいです。なぜなら、投げを行うことを期待するものを正確に示すことができるからです。 –

+1

@AndyTurner私は、あなたが単一のユニットテストで 'SomeException'を投げることができるものが複数ある場合、そのユニットテストを分割する必要があると主張します。 –

+0

@JoeCはい、しかし:最も単純なテストを除いて、あなたはおそらくテストケース固有の設定を行うための作業をしています。あなたが捉えているものによっては、これらの設定アクションの1つが同じ例外をスローし、実際にはテストに合格しない印象を与えてしまうかもしれません。 –

答えて

0

ルールを使用することが効果的かもしれません。

ルールでは、テストクラス内の各テストメソッドの動作を非常に柔軟に追加または再定義できます。テスターは、以下のルールの1つを再利用または拡張したり、独自のルールを作成したりすることができます。

あなたがここにjunit4のこのきちんとした機能の詳細を読むことができます:

https://github.com/junit-team/junit4/wiki/Rules

例:

public static class HasExpectedException { 
    @Rule 
    public final ExpectedException thrown = ExpectedException.none(); 

    @Test 
    public void throwsNullPointerException() { 
      thrown.expect(NullPointerException.class); 
      throw new NullPointerException(); 
    } 
} 
1

私がキャッチ例外のことを聞いたことがないが、それはdoesnの最新のライブラリのように見えます。主なソースコードの最終更新は(書面の時点で)on May 3 2015でした。

は、Java 8使用している、と後でJUnitの4.13を使用したりすることができた場合、あなたはassertThrows使用することができます。

assertThrows(
    UserAlreadyDeletedException.class, 
    () -> sut.deleteCurrentlyLoggedInUser(principalStub)); 

は、あなたが何かにあなたのコードのすべてを移行するつもりなら、これはのように思えますより良い長期賭け。

+0

Spring Bootを使用しているときにJunit 4.13を使用する方法を知っていますか?私はまだMaven Repoでこのバージョンを見ることができません。 – doublemc

+0

この機能はJUnit 5にも含まれていますが、4.13と5.0の両方が公開されていません(まだRCまたはスナップショットのいずれのバージョンでも)。だからこそ公式のリポジトリでバージョンを見つけることができないのです。:) – vegaasen

関連する問題