如何在Junit测试中获取服务对象?

时间:2018-03-14 17:54:13

标签: java spring-boot

我有一个Springboot项目并且有一个服务类:

@Service("requestService")
public class RequestServiceImpl implements RequestService {

    @Autowired
    QueryService queryService;

    public RequestServiceImpl() {
    }

    public RequestServiceImpl(QueryService queryService) {
        this.queryServce = queryService;
    }

    @Override
    public Response getResponse(QueryInfo queryInfo) {

        return queryService.queryGraph(queryInfo);
    } 
}

在我的JUnit测试中,我想测试这个类:

public class RequstServiceTest {

      @Mock 
      QueryService queryService;

@Test
public void testRequestInfo() {

     // I can't do this
     RequestService requestService = new 
     RequestServiceImpl(queryService);
     ...
     requestService.getResponse(queryInfo); 
}

如何在我的测试环境中注入ReqeustServiceImpl的对象?

编辑:在遵循建议并修改上面的代码之后,我仍然在RequestServiceImpl中获得'queryService'的空指针异常。

SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)

  at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
  at com.sun.proxy.$Proxy22.isTypeMockable(Unknown Source)
  at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
  at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
  at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:232)
  at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:226)
  at org.mockito.internal.MockitoCore.mock(MockitoCore.java:64)
  at org.mockito.Mockito.mock(Mockito.java:1864)
  at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:36)
  at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
  at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:38)
  at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:62)
  at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:57)
  at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:41)
  at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:69)
  at com.qt.service.LocalServiceTest.doSetup(LocalServiceTest.java:35)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
  at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NoClassDefFoundError: org/mockito/cglib/proxy/MethodInterceptor
  at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.<init>(PowerMockMaker.java:43)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  at java.lang.Class.newInstance(Class.java:442)
  at org.mockito.internal.configuration.plugins.PluginInitializer.loadImpl(PluginInitializer.java:49)
  at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:57)
  at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:44)
  at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:21)
  at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:18)
  at org.mockito.internal.configuration.GlobalConfiguration.tryGetPluginAnnotationEngine(GlobalConfiguration.java:55)
  at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:68)
  ... 23 more
Caused by: java.lang.ClassNotFoundException: org.mockito.cglib.proxy.MethodInterceptor
  at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  ... 36 more

1 个答案:

答案 0 :(得分:2)

在此处输入代码@Mock注释只声明可以由Mockito注入的引用。要触发模拟的实际注入,请将以下内容添加到测试方法中。

MockitoAnnotations.initMocks(this);

请参阅:https://static.javadoc.io/org.mockito/mockito-core/2.2.28/org/mockito/MockitoAnnotations.html#initMocks(java.lang.Object)

由于这是一个类级变量,看起来你希望能够在测试方法中使用这个模拟,所以一个好的方法是使用@Before方法。使用@Before注释的方法将在每个测试方法之前执行,从而确保每个测试都具有模拟的新初始化版本。

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