spring - 模拟基本抽象类的自动装配对象
问题描述
我正在为一个由抽象类扩展的类编写 Junit 测试用例。这个基础抽象类有一个不同类的自动装配对象,该对象正在我正在测试的类中使用。我正在尝试在子类中进行模拟,但被模拟的对象正在抛出 NullPointerException。
例子:
// class I am testing
public class GetTransactionsForProcessorGroupActivity extends GetTransactionsBaseActivity {
private static final Logger log = LogManager.getLogger(GetTransactionsForProcessorGroupActivity.class);
public GetTransactionsForProcessorGroupActivity(ARHFactory arhFactory, MetricsFactory metricsFactory) {
super(arhFactory, metricsFactory);
}
@Override
protected List<OverseasTransaction> getOverseasTransactions(Document herdDocument)
throws IllegalDateFormatException, ProcessorConfigurationException, DocumentException {
final String paymentProcessorGroup = HerdDocumentUtils.getPaymentProcessor(herdDocument);
final Date runDate = HerdDocumentUtils.getRunDate(herdDocument);
final List<String> paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup);
List<OverseasTransaction> overseasTransactionList = new ArrayList<OverseasTransaction>();
List<ProcessorTransactionWindow> processingWindows = new ArrayList<ProcessorTransactionWindow>();
for (final String processor : paymentProcessorList) {
ProcessorTransactionWindow transactionWindow = ProcessorCalendarUtils.getProcessorTransactionWindow(processor, runDate);
processingWindows.add(transactionWindow);
final Date processingFromDate = transactionWindow.getFromDate();
final Date processingToDate = transactionWindow.getToDate();
//NullpointerException on this line, as OverseasTransactionStore mock object returns null.
final List<OverseasTransaction> transactions = overseasTransactionsStore
.queryOverseasTransactionsOnPPTimelineandDates(processor, processingFromDate, processingToDate);
overseasTransactionList.addAll(transactions);
}
HerdDocumentUtils.putProcessingWindowDetails(herdDocument, processingWindows);
return overseasTransactionList;
}
}
// Base class
public abstract class GetTransactionsBaseActivity extends CoralHerdActivity implements ActionRequestHandler {
private static final Logger log = LogManager.getLogger(GetTransactionsBaseActivity.class);
@SuppressWarnings("unchecked")
private static final Map<String, String> S3_CONFIGURATION = AppConfig.findMap(Constants.S3_CONFIGURATION_KEY);
private static final String S3_BUCKET = S3_CONFIGURATION.get(Constants.BUCKET_NAME);
private static final class Status {
private static final String PROCESSOR_DETAILS_NOT_FOUND = "NoPaymentProcessorDetailsPresent";
private static final String TRANSACTIONS_OBTAINED = "TransactionsObtained";
private static final String NO_TRANSACTIONS_TO_BE_CONSIDERED = "NoTransactionsToBeConsidered";
private static final String NEGATIVE_OR_ZERO_AMOUNT = "NegativeOrZeroAmount";
}
protected final ARHFactory arhFactory;
protected final MetricsFactory metricsFactory;
@Autowired
OverseasTransactionsStore overseasTransactionsStore;
@Autowired
S3ClientProvider s3ClientProvider;
protected abstract List<OverseasTransaction> getOverseasTransactions(Document herdDocument)
throws IllegalDateFormatException, ProcessorConfigurationException, DocumentException;
@Override
public ActionResponse postActionRequest(final ActionRequest request) throws Exception {
TimedARH timedARH = (TimedARH) arhFactory.createARH();
timedARH.setHandler(this);
return timedARH.handle(request);
}
public ActionResponse handle(final ActionRequest request) throws Exception {
final Document herdDocument = HerdDocumentUtils.getFundFlowDocument(request);
final Metrics metrics = MetricsLogger.getMetrics(metricsFactory);
final String paymentProcessor = HerdDocumentUtils.getPaymentProcessor(herdDocument);
try {
final List<OverseasTransaction> overseasTransactionList;
MetricsLogger.logFundFlowExecution(metrics, paymentProcessor);
try {
overseasTransactionList = getOverseasTransactions(herdDocument);
} catch (ProcessorConfigurationException e) {
return new ActionComplete(Status.PROCESSOR_DETAILS_NOT_FOUND, herdDocument);
}
if (CollectionUtils.isEmpty(overseasTransactionList)) {
MetricsLogger.logTransactionMetrics(metrics, paymentProcessor, 0, BigDecimal.ZERO);
return new ActionComplete(Status.NO_TRANSACTIONS_TO_BE_CONSIDERED, herdDocument);
}
final String s3ObjectKey = getS3ObjectKey(request, paymentProcessor);
storeTransactionsInS3(overseasTransactionList, S3_BUCKET, s3ObjectKey);
final int itemCount = overseasTransactionList.size();
BigDecimal totalAmount = BigDecimal.ZERO;
for (OverseasTransaction overseasTransaction : overseasTransactionList) {
if (StringUtils.equalsIgnoreCase(overseasTransaction.getType(), Constants.TRANSACTION_TYPE_CHARGE)) {
totalAmount = totalAmount.add(overseasTransaction.getOverseasAmount());
} else if (StringUtils.equalsIgnoreCase(overseasTransaction.getType(), Constants.TRANSACTION_TYPE_REFUND)) {
totalAmount = totalAmount.subtract(overseasTransaction.getOverseasAmount());
}
}
MetricsLogger.logTransactionMetrics(metrics, paymentProcessor, itemCount, totalAmount);
HerdDocumentUtils.putS3Location(herdDocument, S3_BUCKET, s3ObjectKey);
HerdDocumentUtils.putTotalAmount(herdDocument, totalAmount);
HerdDocumentUtils.putTransactionItemCount(herdDocument, itemCount);
HerdDocumentUtils.putPaymentProcessor(herdDocument, paymentProcessor);
if (totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
log.info("Total amount to disburse is zero or negative. {}", totalAmount);
return new ActionComplete(Status.NEGATIVE_OR_ZERO_AMOUNT, herdDocument);
}
return new ActionComplete(Status.TRANSACTIONS_OBTAINED, herdDocument);
} finally {
MetricsLogger.closeMetrics(metrics);
}
}
}
// Test class
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({ "javax.management.*" })
@PrepareForTest({ HerdDocumentUtils.class, ProcessorGroupLookup.class })
public class GetTransactionsForProcessorGroupActivityTest extends AppConfigInitializedTestBase {
private static HerdInput herdInput;
private static HerdOutput herdOutput;
private static final String paymentProcessorGroup = "BillDesk";
private static final String paymentProcessorGroupNotFound = "IndiaPaymentGateway";
@Mock
ActionRequest request;
@Mock
WorkItemIdentifier workItemId;
@Mock
private CoralHerdActivity coralHerdActivity;
@Mock
Metrics metrics;
@Mock
Map<String, String> S3_CONFIGURATION_MAP;
@Mock
MetricsFactory metricsFactory;
@Mock
ARHFactory arhFactory;
@Mock
Document herdDocument;
@Mock
OverseasTransactionsStore overseasTransactionsStore;
@Mock
S3ClientProvider s3ClientProvider;
// @InjectMocks
// GetTransactionsForProcessorGroupActivity getTransactionsBaseActivityTest;
// new GetTransactionsForProcessorGroupActivity(arhFactory, metricsFactory);
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(HerdDocumentUtils.class);
// PowerMockito.mockStatic(ProcessorGroupLookup.class);
// GetTransactionsBaseActivity getTransactionsBaseActivity = new GetTransactionsBaseActivity(overseasTransactionsStore);
}
@Test
public void testEnact() {
GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity = Mockito
.mock(GetTransactionsForProcessorGroupActivity.class, Mockito.CALLS_REAL_METHODS);
Mockito.when(coralHerdActivity.enact(herdInput)).thenReturn(herdOutput);
final HerdOutput actualHerdOutput = getTransactionsForProcessorGroupActivity.enact(herdInput);
Assert.assertNotNull(actualHerdOutput);
}
@Test
public void testgetpaymentProcessorList() throws Exception {
Date date = new Date();
List<String> paymentProcessorList;
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument)).thenReturn(paymentProcessorGroup);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup);
assertNotNull(paymentProcessorList);
}
@Test(expected = ProcessorConfigurationException.class)
public void testpaymentProcessorListNotFound() {
Date date = new Date();
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument))
.thenReturn(paymentProcessorGroupNotFound);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
List<String> paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroupNotFound);
assertNotNull(paymentProcessorList);
}
@Test
public void canGetOverseasTransactiontest() throws Exception {
GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity = Mockito
.mock(GetTransactionsForProcessorGroupActivity.class);
// OverseasTransactionsStore overseasTransactionsStore =
// Mockito.mock(OverseasTransactionsStoreImpl.class);
Date date = new Date();
MockitoAnnotations.initMocks(this);
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument)).thenReturn(paymentProcessorGroup);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
// List<String> paymentProcessorList = new ArrayList<>();
// paymentProcessorList.add("BillDesk");
// PowerMockito.when(ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup))
// .thenReturn(paymentProcessorList);
String fromDate = "Sat Mar 16 23:59:59 IST 2019";
String toDate = "Sat Mar 16 23:59:59 IST 2019";
DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
List<OverseasTransaction> overseasTransactionList1 = createMockOverseasTransaction();
Mockito.doReturn(overseasTransactionList1).when(overseasTransactionsStore)
.queryOverseasTransactionsOnPPTimelineandDates(Mockito.isA(String.class), Mockito.isA(Date.class),
Mockito.isA(Date.class));
Mockito.when(getTransactionsForProcessorGroupActivity.getOverseasTransactions(herdDocument))
.thenCallRealMethod();
List<OverseasTransaction> overseasTransactionList = getTransactionsForProcessorGroupActivity
.getOverseasTransactions(herdDocument);
assertNotNull(overseasTransactionList);
// assertEquals(overseasTransactionList.getPaymentProcessorID(), actual);
}
private List<OverseasTransaction> createMockOverseasTransaction() {
Date date = new Date();
BigDecimal num = new BigDecimal(100001);
List<OverseasTransaction> overseasTransactionList = new ArrayList<OverseasTransaction>();
OverseasTransaction overseasTransaction = new OverseasTransaction();
overseasTransaction.setPurchaseID("purchaseID");
overseasTransaction.setSignatureID("signatureID");
overseasTransaction.setPaymentProcessorTransactionID("paymentProcessorTransactionID");
overseasTransaction.setType("Charge");
overseasTransaction.setSubType("subType");
overseasTransaction.setTransactionTimestamp(date);
overseasTransaction.setPaymentMethod("paymentMethod");
overseasTransaction.setTotalAmount(num);
overseasTransaction.setOverseasAmount(num);
overseasTransaction.setCurrency("currency");
overseasTransaction.setMarketplaceID("marketplaceID");
overseasTransaction.setOrderMetadata("orderMetadata");
overseasTransaction.setDisbursementID("disbursementID");
overseasTransaction.setReconState(1);
overseasTransaction.setPaymentProcessorID("BillDesk");
overseasTransaction.setRemittanceFileStatus("remittanceFileStatus");
overseasTransaction.setCrowID("crowID");
overseasTransaction.setSource("source");
overseasTransactionList.add(overseasTransaction);
return overseasTransactionList;
}
}
在我的测试文件中,当我模拟 OverseasTransaction 对象时,它给了我一个 NullPointerException。你对我们如何模拟这个有什么建议吗?我的测试中所有上述注释行都表明我尝试过的事情,但它们似乎仍然抛出相同的错误。
StackTrace 错误:执行canGetOverseasTransactiontest 时
不适用
java.lang.NullPointerException
at com.ingsfundflowservice.activity.GetTransactionsForProcessorGroupActivity.getOverseasTransactions(GetTransactionsForProcessorGroupActivity.java:71)
at com.ingsfundflowservice.activity.GetTransactionsForProcessorGroupActivityTest.canGetOverseasTransactiontest(GetTransactionsForProcessorGroupActivityTest.java:172)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
解决方案
您需要创建要为其编写测试的 Class 对象。即GetTransactionsForProcessorGroupActivity。你可以做些什么
@RunWith(MockitoJUnitRunner.class)
public class GetTransactionsForProcessorGroupActivityTest {
@InjectMocks
private GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity;
@Mock
private OverseasTransaction overseastransaction;
@Test
public void test() {
Mockito.when(overseastransaction.somemethod()).thenReturn(something);
}
}
这将确保创建 getTransactionsForProcessorGroupActivity 并使用模拟对象注入海外事务。
请注意类注释@RunWith。这确保所有属性都正确注入了模拟对象。此外,您可以使用 Mockito 代替 PowerMockito。
推荐阅读
- html - 如何通过按 Tab 键来选择图标/跨度?
- nosql - 喜欢 nosql 数据库 (DynamoDb) 中的帖子
- kubernetes - Kubernetes - 我什么时候应该考虑在 Kubernetes 或常规服务 docker 上使用无服务器
- css - 如何重构媒体查询中的常用 css 规则?
- browserify - 如何在浏览器中使用 Browserify 请求文件?
- javascript - 检测页面级别的滑动(左右)
- javascript - 如何强制 Puppeteer 等到非常大的 HTML 表中的所有行都完全加载并显示在 DOM 中
- python - Python 3.7.4 从官方网站下载,但我安装了 python 2.7.10
- flutter - Flutter:增加 SwitchListTile 图标的大小
- c# - 执行了 SQLite 插入,但记录不在数据库中