我有一个扩展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/