2013-09-06 5 views
0

현재 특정 상황에서 주어진 클래스의 코드 커버리지를 인식하지 못하여 Cobertura으로 어려움을 겪고 있습니다. 클래스가 완전히 테스트되었지만 (Coverageura 100 % 적용) Cobertura는 0 %의 적용 범위를 표시합니다.Cobertura가 완전히 테스트 한 클래스를 인식하지 못합니다.

올바른 패키지 커버리지 결과를 얻는 다른 패키지가 같은 패키지에 있으므로 잘못된 제외 패턴은이 경우 아무런 문제가되지 않습니다.

@Service 
public class CacheEnabledService { 

    @Autowired 
    private UserRepository userRepository; 


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

테스트 자체 : 다음과 같이 테스트 할

클래스는 보이는

내 유일한 가정은 지금까지 어쩌면 하나 스프링스 프록시 및/또는 캐싱 메커니즘 Coberturas 방해이었다
@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); 
    } 
} 

계측.

이 문제를 해결하는 방법에 대한 모든 힌트를 환영합니다. 미리 감사드립니다.

업데이트 : 서비스 클래스에 인터페이스를 추가하면 문제가 해결되었습니다. 누락 된 인터페이스는 Spring에 의해 올바르게 처리되지만이를 달성하기 위해 일부 CGLIB 조작이 필요합니다. 필자의 경우 CGLIB에 의한 이러한 재 매핑은 Cobertura를 능가했다. 따라서 문제를 다시 매핑 할 경우 Spring 서비스가 인터페이스를 사용하는지 항상 확인하십시오. 그냥 주어진 정보를 바탕으로 추측

+1

입니다 주석 경우 그 가치 시도는)

(보고, 또한 @Cacheable를 제거하면 그것을 적용 범위를 제공하는 경우 볼 가치가있을 수도 있습니다 AOP 같은 냄새가 클래스를 다시 매핑합니다. 'cacheEnabledService.getClass(). getName()'을 출력하거나'cacheEnabledService. '를 체크하면 어떻게 될까?getClass() == CacheEnabledService.class' 그들은 같은 클래스가 아니라는 것을 알게 될 것입니다. Cobertura가 메소드가 호출되는 클래스를 추적 할 때, 여러분은 여러분이 보았던 범위를 왜보고 있는지 설명 할 수 있습니다. –

+0

Maven과 같은 것을 사용하고 테스트가 실행되는 여러 모듈을 가지고 있습니까? –

+0

@ BruceLowe 예, 우리는 maven을 사용하는 다중 모듈 빌드 설치가 있습니다. 왜 이것이 중요하다고 생각하니? – u6f6o

답변

1

: 당신은 멀티 모듈 받는다는 프로젝트를 실행하면

(1), 다른 모듈의 테스트를 찾을 수는 @Cacheable 방법의 캐시를 채 웁니다. Cobertura는 프로젝트 레벨이 아닌 모듈 레벨에서만 작동합니다. 따라서 모듈 A의 테스트가 모듈 B의 @Cacheable 메소드를 호출하면 캐시를 채울 수 있지만 모듈 B의 메소드의 코드 적용 범위에는 포함되지 않습니다.

이어서 모듈 B에서 실행되는 테스트는 캐시 된 결과를 얻고 해당 메소드로 이동하지 않으므로 cobertura는 메소드가 적용되지 않았다고 생각할 수 있습니다.

나는 당신이 문맥을 더럽 히고있는 것을 볼 수 있습니다. 테스트가 실행되기 전에 캐시가 지워져야합니다. 따라서 테스트를 실행하기 전에 캐시가 채워져 있지는 않습니다.

가능한 원인 인 경우 테스트를 시작하기 전에 수동으로 캐시를 지우는 것이 좋습니다.

이렇게하려면 캐시 관리자에 @Autowired를 삽입하고 @Before 섹션에 캐시 관리자를 사용하여 해당 메소드의 캐시를 지우십시오.

커버리지 문제가 해결되었는지 확인해보십시오.

(2) 그 나던 그것을 해결하면, 내가 그 cobertura 프록시 문제를 잘 재생되지 중 하나 인 향하다 것 - 아마도 CacheEnabledService가 있는지 확실하지 않습니다 (즉를 해결할 인터페이스에 대한 인터페이스 및 테스트를 구현하기 그 도움이 될 것입니다,하지만 확실히 문제의 근본 원인)

+1

늦은 답변과 올바른 방향으로 나를 가리킨 힌트에 대한 죄송합니다! 제안을 확인하는 동안 내 서비스 클래스에 인터페이스가 없다는 사실을 갑자기 깨달았습니다. Afaik, Spring은 누락 된 인터페이스를 처리하기 위해 CGLIB를 사용하고 약간의 재 매핑을 적용합니다. 인터페이스를 추가 한 후 Cobertura는 예상대로 작동했습니다. 따라서 서비스에 인터페이스를 추가하는 것은 여전히 ​​유효합니다. 특히 Cobertura를 사용하는 경우 더욱 그렇습니다. – u6f6o

+0

위대한, 나는 전에 그것을 알아 챘다. 불쌍한 당신은 문제를 해결하기 위해 인터페이스를 도입해야합니다. 나는 1 개의 구현을위한 인터페이스의 팬인 적이 없다. –

+0

전적으로 동의합니다. 단 1 개의 구현을위한 인터페이스를 정의한다고해서 내 생각에 그렇게 이해가되지는 않는다. – u6f6o

관련 문제