0

私は現在、特定の状況で特定のクラスのコード カバレッジをCoberturaが認識しないことに苦労しています。クラスは完全にテストされていますが (メソッド カバレッジ 100%)、Cobertura は 0% のカバレッジを表示します。

同じパッケージには、適切なコード カバレッジ結果を取得する他のクラスもあるため、この場合、間違った除外パターンは問題になりません。

テストするクラスは次のようになります。

@Service
public class CacheEnabledService {

    @Autowired
    private UserRepository userRepository;


    @Cacheable(value="users",key="#root.methodName")
    public List<User> findAllUser() {
        return userRepository.findAll();
    }
}

テスト自体:

@DirtiesContext
@ContextConfiguration(classes = {TestConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class CacheEnabledServiceTest {

    @Autowired
    private CacheEnabledService cacheEnabledService;


    @Test
    public void testCachedRepoisotryFindAll(){
        UserRepository mockedRepository = Mockito.mock(UserRepository.class);
        cacheEnabledService.setUserRepository(mockedRepository);

        Mockito.when(mockedRepository.findAll()).thenReturn(Lists.<User>newArrayList(new User()));

        List<User> allExpandables1 = cacheEnabledService.findAllUser();
        List<User> allExpandables2 = cacheEnabledService.findAllUser();

        assertEquals(1, allExpandables1.size());
        assertEquals(allExpandables1.size(), allExpandables2.size());
        assertSame(allExpandables1.get(0), allExpandables2.get(0));

        Mockito.verify(mockedRepository, VerificationModeFactory.times(1)).findAll();
        Mockito.verifyNoMoreInteractions(mockedRepository);
    }
}

これまでの私の唯一の仮定は、Springs のプロキシおよび/またはキャッシュ メカニズムのいずれかが Coberturas のインストルメンテーションに干渉する可能性があるということでした。

この問題を解決する方法のヒントは大歓迎です。前もって感謝します。

更新: サービス クラスにインターフェイスを追加すると、問題が修正されました。欠落しているインターフェースは Spring によって正しく処理されますが、これを実現するには CGLIB 操作が必要です。私の場合、CGLIB によるこれらの再マッピングは、Cobertura を打ち負かしました。したがって、再マッピングの問題がある場合は、Spring サービスがインターフェースを使用しているかどうかを常に確認してください。

4

1 に答える 1

1

与えられた情報に基づいて推測するだけです:

(1) マルチモジュール Maven プロジェクトを実行すると、別のモジュールのテストが @Cacheable メソッドのキャッシュに入力されることがあります。Cobertura は、プロジェクト レベルではなく、モジュール レベルでのみ機能します。そのため、モジュール A のテストがモジュール B の @Cacheable メソッドを呼び出す場合、キャッシュに値が入力される可能性がありますが、モジュール B のメソッドのコード カバレッジにはカウントされません。

その後、モジュール B で実行されるテストはキャッシュされた結果を取得し、そのメソッドには入りません。

コンテキストを汚していることがわかります。ただし、これにより、テストの実行前ではなく、テストの実行後にキャッシュがクリアされるはずです。そのため、テストの実行前にキャッシュが読み込まれないことは保証されません。

これが考えられる原因である場合は、テストを開始する前にキャッシュを手動でクリアすることをお勧めします。

これを行うには、キャッシュ マネージャーに @Autowired を挿入し、@Before セクションでキャッシュ マネージャーを使用してそのメソッドのキャッシュをクリアします。

試してみて、カバレッジの問題が解決されるかどうかを確認してください。

(2)それでも解決しない場合は、プロキシの問題をうまく処理できないcoberturaの1つであることに傾倒します-おそらく CacheEnabledService にインターフェイスを実装させ、インターフェイスに対してテストすることで解決します(それが役立つかどうかはわかりませんが、しかし、試してみる価値があります)

( @Cacheable を削除することでカバレッジが得られるかどうかを確認して、それが間違いなく問題の根本原因であるアノテーションであるかどうかを確認することも価値があるかもしれません)

于 2013-09-07T14:48:31.343 に答える