用里面的处理器测试石英作业

时间:2014-08-19 07:14:25

标签: spring quartz-scheduler easymock

我有一些处理器whitch执行一些任务。它有注释Component

@Component
public class Processor implements IProcessor {

@Autowired
private ConsumerTemplate consumerTemplate;

@Autowired
private IMessageService messageService;

@Override
public void process() {
    Message message = consumerTemplate.receive("activemq:queue").getIn(); //line 37
    String id = (String) message.getBody();
    StatusEnum status = StatusEnum.valueOf((String) message.getHeader("status"));
    if (status.equals(StatusEnum.CUSTOM)) {
        String exceptionMessage = (String) message.getHeader("exception_message");
        messageService.updateStatus(id, status, exceptionMessage);
    } else {
        messageService.updateStatus(id, status);
    }
}

}

用于石英作业

public class ProcessingJob extends QuartzJobBean {
private IProcessor processor;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    processor.process();
}

public void setProcessor(IProcessor processor) {
    this.processor = processor;
}

}

我想用

测试它
public class ProcessingJobTest {

private ProcessingJob notificationProcessingJob;
private IProcessor processor;
private JobExecutionContext context;

@Before
public void setUp() {
    processingJob = createMock(ProcessingJob.class);
    processor = new Processor();
    context = createMock(JobExecutionContext.class);
}

@Test
public void testExecuteInternal() throws JobExecutionException {
    processor.process(); // line 40
    expectLastCall();
    replay(processingJob);

    processingJob.executeInternal(context);
    verify(processingJob);
}

}

但我有错误

java.lang.NullPointerException
at com.processor.Processor.process(Processor.java:37)
at com.scheduler.ProcessingJobTest.testExecuteInternal(ProcessingJobTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

为什么呢?问题是什么?

1 个答案:

答案 0 :(得分:1)

字段ConsumerTemplate consumerTemplate未初始化,因此null因此是NPE。

Spring DI在单元测试中默认不起作用,JUnit对@Autowired@Component一无所知。如果你真的想走这条路,你应该看一下集成测试章节:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#integration-testing

我个人更喜欢将您的实现更改为构造函数注入,这会使测试SUT更容易(并且非常清楚为什么您的测试失败):

@Component
public class Processor implements IProcessor {

  private ConsumerTemplate consumerTemplate;
  private IMessageService messageService;

  @Autowired
  public Processor(ConsumerTemplate consumerTemplate, IMessageService messageService){
    this.consumerTemplate = consumerTemplate;
    this.messageService = messageService;
  }

  ...
}

引用Oliver Gierkes post  Field injections is evil… hides dependencies, instead of making them explicit