如果要注入的实例具有最终类,如何使用InjectMocks

And*_*s_D 7 java logback mockito cdi

我想用mockito测试一些服务.这些服务基于CDI,不幸的是,使用现场注入,我无法改变.

public class Service {
   @Inject Logger logger;

   public void method() {
      logger.info("some log text");
  }
}
Run Code Online (Sandbox Code Playgroud)

现在使用mockito的@InjectMocks注释创建可测试的实例非常容易.它将注入嘲笑和间谍.

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
  @Spy Logger logger = LoggerFactory.getLogger(Service.class);

  @InjectMocks Service service;

  @Test public void test() {
     // Given
     // When
     service.method();
     // Then
  }
Run Code Online (Sandbox Code Playgroud)

我需要将一些工作记录器注入我正在测试的服务类中.记录器框架是slf4j,首选记录器是logback.但不幸的Logger是,logback的实现是最终的,所以我不能窥探它,它会导致运行时异常.

我想到的解决方法:

  • 使用反射来初始化服务上的记录器属性(穷人的注射)
  • 实现一个spyable(非最终)记录器包装器,它委托给最终的logback记录器

但对于那些(那些)问题,是否有一个干净或至少更好的解决方案?

Rog*_*rio 2

您的被测类很可能错误地使用了 Logback。不应将该logger字段声明为 type ch.qos.logback.classic.Logger,而应该是接口 type org.slf4j.Logger,该接口由最终的 Logback 记录器类实现。

这样,您就可以避免该问题,因为没有要final模拟或注入的类。