如何使用 Powermockito 在 public class 中模拟静态方法?
How to mock a static method in side a public class using Power mockito?
大家好,我正在尝试模拟一个静态方法名称 mapCreditInfo(UCIPin, creditAssessmentResults),它有两个参数 UCIPin 和 creditAssessmentResults。 UCIPin为String类型,creditAssessmentResults为List
此方法在 public class ResponseMapper 中
键入如下所示:
private CreditInfo getAccountByUCI(String audiUser, String UCIPin) throws EnterpriseCustomerVerificationException {
List<CreditAssessmentResult> creditAssessmentResults = creditInfoRepository.getUCISummary(UCIPin, audiUser);
return ResponseMapper.mapCreditInfo(UCIPin, creditAssessmentResults);
}
Note: getAccountbyUCI method is called inside another public method
name executeCustomerVerification which is in the class
EnterpriseCustomerVerificationService
ResponseMapper class
public class ResponseMapper {
public static CreditInfo mapCreditInfo(String UCIPin, List<CreditAssessmentResult> creditAssessmentResults) {
CreditInfo creditInfo = new CreditInfo();
creditInfo.setUCIPin(UCIPin);
List<AccountCreditInfo> accountCreditInfos = new ArrayList<AccountCreditInfo>();
for (CreditAssessmentResult creditAssessmentResult : creditAssessmentResults) {
AccountCreditInfo accountCreditInfo = new AccountCreditInfo();
accountCreditInfo.setDelinquenctBalance(creditAssessmentResult.getPastDueAmount());
accountCreditInfo.setNonPayDisconnect(creditAssessmentResult.getNonpayDiscount());
accountCreditInfo.setPreviousAccountNumber(creditAssessmentResult.getAccountNumber());
accountCreditInfo.setUnreturnedEquipmentFlag(creditAssessmentResult.getUnreturnedEquipment());
accountCreditInfos.add(accountCreditInfo);
}
creditInfo.setAccountCreditInfo(accountCreditInfos);
return creditInfo;
}
}
我已经试过我测试的某些部分class,如下所示:
测试Class
@PrepareForTest( EnterpriseCustomerVerificationService.class)
@RunWith(PowerMockRunner.class)
public class EnterpriseCustomerVerificationServiceTest {
@InjectMocks
private EnterpriseCustomerVerificationService enterpriseCustormerVerificationServiceMock ;
@Test
public void executeCustomerVerificationTest() throws Exception {
List<ErrorResponse> errorResponses = getErrorResponse();
List<String> mso = new ArrayList<String>();
mso.add("a");
mso.add("b");
mso.add("c");
AddressResponse addressResponse = getAddressResponse();
String experianAuthorization = "experianAuthorization";
String UCIPin = "110019";
String auditUser = "ABC";
CreditInfo credit = getCreditInfo();
CreditCheck creditCheck = getcreditCheck();
EnterpriseCustomerVerificationService spy = PowerMockito.spy(new EnterpriseCustomerVerificationService());
PowerMockito.when(spy,PowerMockito.method(EnterpriseCustomerVerificationService.class,"executeCreditCheck",CreditCheck.class)).withArguments(Mockito.any()).thenReturn("@1");
Mockito.when(creditInfoRepository.getUCISummary("110019", "test")).thenReturn(getCreditAssessmentResultList());
PowerMockito.mockStatic(ResponseMapper.class);
Mockito.when(ResponseMapper.mapCreditInfo(UCIPin, getCreditAssessmentResultList())).thenReturn(credit);
CustomerVerification cv = spy
.executeCustomerVerification(getCustomerVerificationRequest1(),
"101");
}
我的问题是如何使用 power Mockito 模拟 static mapCreditInfo 方法?
谢谢
像这样...
@RunWith(PowerMockRunner.class)
@PrepareForTest({ResponseMapper.class})
public class ATest {
@Test
public void testMockingStatic() {
PowerMockito.mockStatic(ResponseMapper.class);
// if you want to use specific argument matchers
Mockito.when(ResponseMapper.mapCreditInfo(
uciPin, creditAssessmentResults)
).thenReturn(creditInfo);
// or if you want to match on any arguments passed into your static method ...
Mockito.when(ResponseMapper.mapCreditInfo(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyList())
).thenReturn(creditInfo);
// ...
}
}
备注:
@PrepareForTest
使用要模拟的静态方法准备 class
PowerMockito.mockStatic
模拟所有 class 的静态方法
- 您可以使用标准 Mockito when/then 构造来告诉模拟静态方法要做什么 return
- 上面的示例使用了这些依赖项:
org.mockito:mockito-core:2.7.19
org.powermock:powermock-module-junit4:1.7.0
org.powermock:powermock-api-mockito2:1.7.0
更新 1: 根据您更新的问题显示您的测试方法...
我的示例包括:@PrepareForTest({ResponseMapper.class})
您的测试方法不是准备ResponseMapper
,而是准备EnterpriseCustomerVerificationService
。这就像您正在准备调用具有静态方法的 class 的 class,而不是准备包含静态方法的 class。
我强烈建议创建一个新的测试用例 - 只是暂时的 - 它看起来像我提供的那个,并用它来向自己展示如何模拟静态方法,一旦你对它感到满意,然后将它应用到你的EnterpriseCustomerVerificationServiceTest
.
是否可以更改源代码?如果是这样,也许您可以尝试在根本不使用任何模拟框架的情况下解决问题。
查看我对
的评论
大家好,我正在尝试模拟一个静态方法名称 mapCreditInfo(UCIPin, creditAssessmentResults),它有两个参数 UCIPin 和 creditAssessmentResults。 UCIPin为String类型,creditAssessmentResults为List 此方法在 public class ResponseMapper 中 键入如下所示:
private CreditInfo getAccountByUCI(String audiUser, String UCIPin) throws EnterpriseCustomerVerificationException {
List<CreditAssessmentResult> creditAssessmentResults = creditInfoRepository.getUCISummary(UCIPin, audiUser);
return ResponseMapper.mapCreditInfo(UCIPin, creditAssessmentResults);
}
Note: getAccountbyUCI method is called inside another public method name executeCustomerVerification which is in the class EnterpriseCustomerVerificationService
ResponseMapper class
public class ResponseMapper {
public static CreditInfo mapCreditInfo(String UCIPin, List<CreditAssessmentResult> creditAssessmentResults) {
CreditInfo creditInfo = new CreditInfo();
creditInfo.setUCIPin(UCIPin);
List<AccountCreditInfo> accountCreditInfos = new ArrayList<AccountCreditInfo>();
for (CreditAssessmentResult creditAssessmentResult : creditAssessmentResults) {
AccountCreditInfo accountCreditInfo = new AccountCreditInfo();
accountCreditInfo.setDelinquenctBalance(creditAssessmentResult.getPastDueAmount());
accountCreditInfo.setNonPayDisconnect(creditAssessmentResult.getNonpayDiscount());
accountCreditInfo.setPreviousAccountNumber(creditAssessmentResult.getAccountNumber());
accountCreditInfo.setUnreturnedEquipmentFlag(creditAssessmentResult.getUnreturnedEquipment());
accountCreditInfos.add(accountCreditInfo);
}
creditInfo.setAccountCreditInfo(accountCreditInfos);
return creditInfo;
}
}
我已经试过我测试的某些部分class,如下所示: 测试Class
@PrepareForTest( EnterpriseCustomerVerificationService.class)
@RunWith(PowerMockRunner.class)
public class EnterpriseCustomerVerificationServiceTest {
@InjectMocks
private EnterpriseCustomerVerificationService enterpriseCustormerVerificationServiceMock ;
@Test
public void executeCustomerVerificationTest() throws Exception {
List<ErrorResponse> errorResponses = getErrorResponse();
List<String> mso = new ArrayList<String>();
mso.add("a");
mso.add("b");
mso.add("c");
AddressResponse addressResponse = getAddressResponse();
String experianAuthorization = "experianAuthorization";
String UCIPin = "110019";
String auditUser = "ABC";
CreditInfo credit = getCreditInfo();
CreditCheck creditCheck = getcreditCheck();
EnterpriseCustomerVerificationService spy = PowerMockito.spy(new EnterpriseCustomerVerificationService());
PowerMockito.when(spy,PowerMockito.method(EnterpriseCustomerVerificationService.class,"executeCreditCheck",CreditCheck.class)).withArguments(Mockito.any()).thenReturn("@1");
Mockito.when(creditInfoRepository.getUCISummary("110019", "test")).thenReturn(getCreditAssessmentResultList());
PowerMockito.mockStatic(ResponseMapper.class);
Mockito.when(ResponseMapper.mapCreditInfo(UCIPin, getCreditAssessmentResultList())).thenReturn(credit);
CustomerVerification cv = spy
.executeCustomerVerification(getCustomerVerificationRequest1(),
"101");
}
我的问题是如何使用 power Mockito 模拟 static mapCreditInfo 方法?
谢谢
像这样...
@RunWith(PowerMockRunner.class)
@PrepareForTest({ResponseMapper.class})
public class ATest {
@Test
public void testMockingStatic() {
PowerMockito.mockStatic(ResponseMapper.class);
// if you want to use specific argument matchers
Mockito.when(ResponseMapper.mapCreditInfo(
uciPin, creditAssessmentResults)
).thenReturn(creditInfo);
// or if you want to match on any arguments passed into your static method ...
Mockito.when(ResponseMapper.mapCreditInfo(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyList())
).thenReturn(creditInfo);
// ...
}
}
备注:
@PrepareForTest
使用要模拟的静态方法准备 classPowerMockito.mockStatic
模拟所有 class 的静态方法
- 您可以使用标准 Mockito when/then 构造来告诉模拟静态方法要做什么 return
- 上面的示例使用了这些依赖项:
org.mockito:mockito-core:2.7.19
org.powermock:powermock-module-junit4:1.7.0
org.powermock:powermock-api-mockito2:1.7.0
更新 1: 根据您更新的问题显示您的测试方法...
我的示例包括:@PrepareForTest({ResponseMapper.class})
您的测试方法不是准备ResponseMapper
,而是准备EnterpriseCustomerVerificationService
。这就像您正在准备调用具有静态方法的 class 的 class,而不是准备包含静态方法的 class。
我强烈建议创建一个新的测试用例 - 只是暂时的 - 它看起来像我提供的那个,并用它来向自己展示如何模拟静态方法,一旦你对它感到满意,然后将它应用到你的EnterpriseCustomerVerificationServiceTest
.
是否可以更改源代码?如果是这样,也许您可以尝试在根本不使用任何模拟框架的情况下解决问题。
查看我对