我有一个扩展QuartzJobBean的Java类,并且已安排在当天的特定时间。
public class ServiceJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) {
}
有人可以帮我理解如何为此创建一个Junit测试用例。如何在测试用例中调用executeInternal()方法。
感谢您提供任何帮助。
答案 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;
}
如果您有疑问,请随时通过评论向我询问。