【问题标题】:Inject object in injected service class using Mockito使用 Mockito 在注入的服务类中注入对象
【发布时间】:2015-12-10 03:28:43
【问题描述】:

我正在尝试为我们的 JavaEE7 应用程序中的服务编写 JUnit 测试。 被测服务类注入另一个服务类,后者又注入另一个类。 简而言之,这是我的课程:

class ServiceA {
   ServiceB serviceB;
   public void methodA() {
     serviceB.methodB();
   }
}

class ServiceB {
   @Inject
   ServiceC serviceC;
   public void methodB() {
      serviceC.methodC();
   }
}

class ServiceC {
   public void methodC() {}
}

class TestServiceA {
   @Spy
   ServiceA serviceA;
   @InjectMocks
   ServiceB serviceB;
   @Before
   public void setUp() {
      serviceA.serviceB = mock(ServiceB.class);
   }

   @Test
   public void testServiceA() {
      serviceA.methodA();
   }
}

编辑:从原始 Logger 问题编辑为一般对象问题。 问题是是否有可能或有必要在我的测试中注入多个级别的对象,或者我是否应该只模拟第一个注入的服务并使用 when-Expressions 捕获对后续服务的所有方法调用?

【问题讨论】:

  • 第一个问题是,为什么需要注入记录器而不是简单地询问 LoggerFactory 呢?为什么可以在您的测试中调用serviceA.serviceB = ... 而不是serviceB.log = ...?不太清楚你在问什么...... Mockito 是用来模拟的,你想模拟记录器吗?或者你想要一个真正的记录器的注入逻辑?
  • 其实例子并不局限于注入Logger。我已经将 Logger 更改为使用 LoggerFactory 创建而不是注入它,现在我已经到了在 serviceB 中注入另一个 serviceC 并且我的 mockito 测试失败的地步。但这可能是我需要在测试中使用 when-Expression 来模拟对 serviceC 的调用的时候。
  • 注入 Logger 的一个原因是我们可能想在我们的应用程序中使用不同的 Logger。我们在“Java EE 7 Workshop”一书中看到了一个示例,其中作者列出了一个“TechLogger”和另一个用于不同目的的记录器。不确定这是否有意义。
  • 对于日志记录:您使用的是 slf4j、iirc,所以您不需要它。它是一个日志外观,无论如何都可以配置为使用不同的记录器,无需在您的代码中这样做。只需使用 slf4j api,包括从工厂获取记录器,就可以了。剩下的只是配置 slf4j。

标签: java logging junit dependency-injection mockito


【解决方案1】:

您的目标是测试例如在您使用 serviceA.methodA() 时是否真正调用了 methodB。

下面的代码就是这样做的:

import javax.inject.Inject;

public class ServiceA {

    @Inject
    ServiceB serviceB;

    public void methodA() {
        serviceB.methodB();
    }
}

import javax.inject.Inject;

public class ServiceB {

    @Inject
    Logger log;

    public void methodB() {
        log.debug("log message");
    }
}

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;

public class ServiceTest {

    /**
     * Create an instance of the class ServiceA.
     */
    @InjectMocks
    private ServiceA serviceA;

    /**
     * Create a fake instance of ServiceB.
     */
    @Mock
    private ServiceB serviceB;

    /**
     * Create a fake instance of Logger.
     */
    @Mock
    private Logger log;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    /**
     * Verify that methodB is called.
     */
    @Test
    public void testServiceA() {
        serviceA.methodA();
        verify(serviceB, times(1)).methodB();
    }
}

这里,Logger 也必须是一个 mock,否则你会得到一个 NPE。

【讨论】:

  • 当我试图模拟接口而不是类时,它给了我 NPE。以您为例。我使用的是 IMyInterface 而不是 Logger。你能推荐一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多