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

   public class ServiceJob extends QuartzJobBean {

        @Override
          protected void executeInternal(JobExecutionContext context) {
}

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

感谢您对此的任何帮助。

最佳答案

我为我的工作项目创建了一个解决方案,我同意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 protected ,因此我们必须先调用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;

}

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

关于用于扩展QuartzJobBean的类的Junits,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27552136/

10-09 04:37