如何使用 Powermockito 在 public class 中模拟静态方法?

How to mock a static method in side a public class using Power mockito?

大家好,我正在尝试模拟一个静态方法名称 mapCreditInfo(UCIPin, creditAssessmentResults),它有两个参数 UCIPincreditAssessmentResults。 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.

是否可以更改源代码?如果是这样,也许您可​​以尝试在根本不使用任何模拟框架的情况下解决问题。

查看我对

的评论