扩展QuartzJobBean的类的Junits

时间:2014-12-18 17:16:27

标签: junit

我有一个扩展QuartzJobBean的Java类,并且已安排在当天的特定时间。

   public class ServiceJob extends QuartzJobBean {

        @Override
          protected void executeInternal(JobExecutionContext context) {
}

有人可以帮我理解如何为此创建一个Junit测试用例。如何在测试用例中调用executeInternal()方法。

感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:3)

我为我的工作项目创建了一个解决方案,我同意adarshdatt通过导入定义bean的配置文件来解决它。你可以在blog post

找到一个很好的教程

为了将来的使用,我想展示如何用Mocking解决它,只需用这种方式使用Mockito @Mock注释:

SessionConfirmationJob.java

public class SessionConfirmationJob extends QuartzJobBean {
    @Autowired
    private SessionService sessionService;
    @Autowired
    private TransactionService transactionService;
    @Autowired
    private SystemLogger systemLogger;
    public static final String TOKEN = "token";
    private SpringInjectQuartzJobBean springInjectQuartzJobBean;

    public SessionService getSessionService() {
        return sessionService;
    }

    public void setSessionService(SessionService sessionService) {
        this.sessionService = sessionService;
    }

    public TransactionService getTransactionService() {
        return transactionService;
    }

    public void setTransactionService(TransactionService transactionService) {
        this.transactionService = transactionService;
    }

    public void setSpringInjectQuartzJobBean(SpringInjectQuartzJobBean springInjectQuartzJobBean) {
        this.springInjectQuartzJobBean = springInjectQuartzJobBean;
    }

    public SystemLogger getSystemLogger() {
        return systemLogger;
    }

    public void setSystemLogger(SystemLogger systemLogger) {
        this.systemLogger = systemLogger;
    }

    @Override
    protected void executeInternal(JobExecutionContext paramJobExecutionContext) throws JobExecutionException {
        springInjectQuartzJobBean = new SpringInjectQuartzJobBean();
        springInjectQuartzJobBean.injectQuartzJobToSpringApplicationContext(this);
        String token = paramJobExecutionContext.getMergedJobDataMap().getString(TOKEN);
        Session session = sessionService.getByToken(token);
        if (session != null) {
            if (session.getPaymentConfirmation() == null || session.getPaymentConfirmation() != true) {
                Transaction transactionToBeRolledBack = transactionService.getRollBackTransactionOfPayment(session);
                if (transactionToBeRolledBack != null) {
                    try {
                        transactionService.rollBackTransaction(transactionToBeRolledBack);
                    } catch (IOException e) {
                        systemLogger.logException("Exception while rolling back transaction", e);
                    }
                    session = sessionService.getByToken(token);
                    session.setStatus(SessionStatus.FI);
                    session.setPaymentConfirmation(false);
                    sessionService.saveOrUpdate(session);
                }
            }
        }
    }
}

这是我应该编写测试的方法,这是测试类。

<强> SessionConfirmationJobTest.java

@RunWith(MockitoJUnitRunner.class)
public class SessionConfirmationJobTest {
    @Mock
    private SessionService sessionService;
    @Mock
    private TransactionService transactionService;
    @Mock
    private JobExecutionContext ctx;
    @Mock
    private SpringInjectQuartzJobBean springInjectQuartzJobBean;
    private JobDataMap mergedJobDataMap = new JobDataMap();
    @Mock
    private Scheduler scheduler;
    private SessionConfirmationJob sessionConfirmationJob;
    private String token = "payment token";

    @Before
    public void setUp() throws SchedulerException {
        mergedJobDataMap.put(SessionConfirmationJob.TOKEN, token);
        when(ctx.getMergedJobDataMap()).thenReturn(mergedJobDataMap);
        when(ctx.getScheduler()).thenReturn(scheduler);
        when(scheduler.getContext()).thenReturn(null);
        sessionConfirmationJob = new SessionConfirmationJob();
        sessionConfirmationJob.setSessionService(sessionService);
        sessionConfirmationJob.setTransactionService(transactionService);
        sessionConfirmationJob.setSpringInjectQuartzJobBean(springInjectQuartzJobBean);
    }

    /**
     * Test payment confirmation when we have false payment confirmation
     * 
     * @throws JobExecutionException
     */
    @Test
    public void testPaymentRollBackForFalseConfirmation() throws IOException, JobExecutionException {
        Session session = new Session();
        session.setStatus(SessionStatus.AC);
        session.setPaymentConfirmation(false);
        Transaction transaction = new Transaction();
        transaction.setSession(session);
        transaction.setType(TransactionType.SALE);
        transaction.setStatus(TransactionStatus.AP);
        when(sessionService.getByToken(token)).thenReturn(session);
        when(transactionService.getRollBackTransactionOfPayment(session)).thenReturn(transaction);
        when(transactionService.rollBackTransaction(transaction)).thenReturn(true);
        sessionConfirmationJob.execute(ctx);
        Assert.assertEquals(SessionStatus.FI, session.getStatus());
        Assert.assertFalse(session.getPaymentConfirmation());
        verify(sessionService).saveOrUpdate(session);
    }
}

在模拟Schedular对象之前,我在pvs.addPropertyValues(context.getScheduler().getContext());得到NullPointerException,在我模拟调度后,它被解决并且我的测试通过了。

下面是

org.springframework.scheduling.quartz.QuartzJobBean#execute(JobExecutionContext context)方法。实际上executeInternal是受保护的,所以我们必须首先调用execute方法然后执行方法就是调用executeInternal,它在你实现的Job类中被覆盖(我的演示是SessionConfirmationJob)。

<强> QuartzJobBean.java

public abstract class QuartzJobBean implements Job {

    /**
     * This implementation applies the passed-in job data map as bean property
     * values, and delegates to {@code executeInternal} afterwards.
     * @see #executeInternal
     */
    @Override
    public final void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            MutablePropertyValues pvs = new MutablePropertyValues();
            pvs.addPropertyValues(context.getScheduler().getContext());
            pvs.addPropertyValues(context.getMergedJobDataMap());
            bw.setPropertyValues(pvs, true);
        }
        catch (SchedulerException ex) {
            throw new JobExecutionException(ex);
        }
        executeInternal(context);
    }

/**
 * Execute the actual job. The job data map will already have been
 * applied as bean property values by execute. The contract is
 * exactly the same as for the standard Quartz execute method.
 * @see #execute
 */
protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;

}

如果您有疑问,请随时通过评论向我询问。