Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Cobertura不承认完全测试的类_Java_Spring_Unit Testing_Code Coverage_Cobertura - Fatal编程技术网

Java Cobertura不承认完全测试的类

Java Cobertura不承认完全测试的类,java,spring,unit-testing,code-coverage,cobertura,Java,Spring,Unit Testing,Code Coverage,Cobertura,我目前正在努力解决的问题是,在某些情况下,Cobertura不能识别给定类的代码覆盖率。尽管该类经过了全面测试(方法覆盖率100%),但Cobertura显示的覆盖率为0% 同一个包中还有其他类可以获得正确的代码覆盖率结果,因此在这种情况下,错误的排除模式没有问题 要测试的类如下所示: @Service public class CacheEnabledService { @Autowired private UserRepository userRepository;

我目前正在努力解决的问题是,在某些情况下,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();
    }
}
@服务
公共类CacheEnabledService{
@自动连线
私有用户存储库用户存储库;
@可缓存(value=“users”,key=“#root.methodName”)
公共列表findAllUser(){
返回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);
    }
}
@DirtiesContext
@ContextConfiguration(类={TestConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
公共类CacheEnabledServiceTest{
@自动连线
专用CacheEnabledService CacheEnabledService;
@试验
public void testCachedRepoisotryFindAll(){
UserRepository mockedRepository=Mockito.mock(UserRepository.class);
setUserRepository(mockedRepository);
Mockito.when(mockedRepository.findAll()).thenReturn(Lists.newArrayList(newuser()));
List allExpandables1=cacheEnabledService.findAllUser();
List allExpandables2=cacheEnabledService.findAllUser();
assertEquals(1,allExpandables1.size());
assertEquals(allExpandables1.size(),allExpandables2.size());
assertSame(allExpandables1.get(0),allExpandables2.get(0));
verify(mockedRepository,VerificationModeFactory.times(1)).findAll();
Mockito.verifyNoMoreInteractions(mockedRepository);
}
}
到目前为止,我唯一的假设是Springs代理和/或缓存机制可能会干扰Coberturas检测

欢迎提供解决此问题的任何提示。提前谢谢

更新:
向服务类添加接口修复了该问题。缺少的接口由Spring正确处理,但需要一些CGLIB操作来实现这一点。在我的例子中,CGLIB的这些重映射胜过了Cobertura。因此,如果存在重新映射问题,请始终检查Spring服务是否使用接口

根据给出的信息进行推测:

(1) 如果您运行一个多模块maven项目,您可能会发现另一个模块中的测试填充了@Cacheable方法的缓存。Cobertura只在模块级别工作,而不是在项目级别,因此如果模块a的测试从模块B调用@Cacheable方法,它可能会填充缓存,但是这不计入模块B方法的代码覆盖率

随后在模块B中运行的测试将得到一个缓存结果,而不会进入该方法,因此cobertura可能认为该方法未被涵盖

我看得出你在破坏环境。这应该在测试运行之后而不是之前清除缓存,这样就不会确保在测试运行之前未填充缓存

如果这是可能的原因,我建议您在测试开始之前手动清除缓存

为此,请尝试使用@Autowired注入缓存管理器,并在@Before部分中使用缓存管理器清除该方法的缓存

试试看你的保险问题是否解决了

(2) 如果这不能解决问题,我倾向于认为它是那些不能很好地处理代理问题的cobertura之一——可能是让CacheEnabledService实现一个接口,并针对该接口进行测试将解决这个问题(不确定这是否有帮助,但值得一试)


(可能还值得一看删除@Cacheable是否会覆盖它,看看这是否确实是导致问题的根本原因的注释)

闻起来像是AOP正在重新映射类。如果打印出
cacheEnabledService.getClass().getName()
或检查
cacheEnabledService.getClass()==cacheEnabledService.class
会发生什么情况?我怀疑您会发现它们不是同一个类。。。当Cobertura跟踪调用方法的类时,它可能会解释为什么您会看到覆盖率。您是否使用Maven之类的工具,并且有多个测试正在运行的模块?@BruceLowe是的,我们有一个Maven的多模块构建设置。为什么你认为这很重要?如果你只运行这个类的测试覆盖率会怎么样?在我正在做的一个项目中,我也遇到了同样的问题,但当我只为那门课运行它时,覆盖率是100%。很抱歉我的回答太晚了,谢谢你给我的提示,为我指明了正确的方向!当我检查你的提议时,我突然意识到我的服务类没有接口。另外,Spring使用CGLIB处理缺少的接口,并应用一些重新映射。添加接口后,Cobertura按预期工作。因此,向服务添加接口仍然有效,特别是如果您使用Cobertura。遗憾的是,你必须引入一个接口来解决这个问题。我从来都不是1实现接口的粉丝。我完全同意。在我看来,仅为1个实现定义接口没有多大意义。