多线程如何使用Java并发执行器为代码编写junit测试用例(多线程)
我是多线程新手,有下面的示例代码。我们如何编写具有最大代码覆盖率的单元测试用例
public class jobExecutorImpl<T> implements jobExecutor<T>
{
private AcquisitionProcessor processor;
private ExecutorService jobExecutor;
private AcquisitionProcessExecutor executorService;
@Override
public AcquisitionResponse<T> processContent(Collection<T> itemsToProcess) throws Exception {
AcquisitionResponse<T> acquisitionResponse = new AcquisitionResponse<>();
if(CollectionUtils.isNotEmpty(itemsToProcess)){
// List<Callable<T>> tasks = new ArrayList<Callable<T>>();
// CountDownLatch latch=new CountDownLatch(itemsToProcess.size());
LOGGER.info("Items to Process: "+itemsToProcess.size());
for (T item : itemsToProcess) {
jobExecutor.execute(new Runnable() {
@Override
public void run() {
AcquisitionStatus status= null;
try {
status = executorService.process(item);
} catch (Exception e) {
e.printStackTrace();
//TODO catch filenotfound and throw
}
if(status!=null) {
acquisitionResponse.addStatus(item, status);
}
}
});
// tasks.add(new threadExecutor(item,acquisitionResponse,latch));
}
// jobExecutor.invokeAll(tasks);
}
processor.archiveFile();
return acquisitionResponse;
}
// actually code processed in each thread
public class ProcessExecutor<T>
{
private AcquisitionPreProcessor preProcessor;
private AcquisitionProcessor processor;
private Converter requestConverter;
private Converter responseConverter;
private MediaManagementService mediaManagementService;
private ContentComparator contentComparator;
private MediaContentDAO mediaContentDao;
public AcquisitionStatus process(T item) throws Exception
{
LOGGER.debug("Processing for Id: " + item.toString()+"Thread: "+Thread.currentThread().getName());
Object response = null;
try {
response = processor.processInternal(requestConverter.convert(item));
List<MediaContent> targetList = ((SupplierContent) responseConverter.convert(response)).getMediaContents();
if(CollectionUtils.isNotEmpty(targetList)){
List<MediaContent> sourceList = mediaContentDao.getAllParentMediaContentsByLobTypeAndValue(targetList.get(0).getContentLobValue(), targetList.get(0).getContentLOBType());
List<MediaContent> listOfComparedMediaContents = contentComparator.compare(sourceList,targetList);
int insertCount = 0,deleteCount = 0;
for(MediaContent mediaContent:listOfComparedMediaContents){
if(mediaContent.getActionType().equals(ActionType.DELETE)){
LOGGER.info("Processing delete");
mediaManagementService.deleteContent(mediaContent);
deleteCount = deleteCount + getNumOfMediaContents(mediaContent);
}
if(mediaContent.getActionType().equals(ActionType.INSERT)){
LOGGER.info("Processing insert");
mediaManagementService.insertContent(mediaContent);
insertCount = insertCount + getNumOfMediaContents(mediaContent);
}
}
if(deleteCount + insertCount > 0){
return new AcquisitionStatus(StatusType.Processed, insertCount, deleteCount);
}
}
}catch(FileNotFoundException e)
{
throw e;
}
catch(Exception e) {
handleException(item, e);
return new AcquisitionStatus(StatusType.Error, e);
}
return null;
}
# 1 楼答案
# 2 楼答案
匿名类很难进行单元测试。 如果代码部分的复杂性最低,我不会使用匿名类,原因如下:
查看您的代码:
如果你想改变这一点,这个新的Runnable()就是个问题。 相反,要定义一个匿名类,可以定义一个普通类,例如内部类(例如AquisitionExecutor),并传递一个新实例来执行。 然而,在你的情况下,这似乎不是必要的。在你的例子中,匿名类并不是那么复杂。我可以相信它不会被单元测试所转移
多线程代码不容易进行单元测试。确保单元测试不会在线程终止之前终止。并在线程完成工作后检查预期结果
我通过定义一个ITarget接口来实现这一点,代码使用该接口来转发计算结果。在单元测试的情况下,我用实现ITarget的testCaseClass替换该目标实例