无法使用Mockito对accountStatus进行模拟

huangapple go评论142阅读模式
英文:

Unable to mock accountStatus with Mockito

问题

从下面的代码片段中,我无法模拟 checkAccountStatus 方法,它的返回值为 null。我需要做哪些更改来解决这个问题?

public AccessIDSearchResponse searchAccessID(AccessIDSearchRequest accessIDRequest) {
    String[] productTypes = accessIDRequest.getProductTypes();
    AccountResponse actResponse = checkAccountStatus(accessIDRequest);
    System.out.println("Response is---->" + JsonService.getJsonFromObject(actResponse));
    if (accessIDRequest.getSearchtype().equalsIgnoreCase("accountId") &&
            !Utility.isEmpty(actResponse) &&
            !"FREEVIEW".equalsIgnoreCase(actResponse.getAccountStatus())) {
        errorHandler.error(ErrorMessages.EPO_EXISTINGTV_ERR_07, ErrorMessages.ACCESS_ID_NOT_FOUND);
    }
}

public AccountResponse checkAccountStatus(AccessIDSearchRequest request) {
    AccessIDSearchResponse response = new AccessIDSearchResponse();
    SearchAccessIdContent content = new SearchAccessIdContent();
    DTVNAccountDetails accountDetails = new DTVNAccountDetails();
    accountDetails.setAccountNumber(request.getSearchvalue());
    List<DTVNAccountDetails> list = new ArrayList<>();
    list.add(accountDetails);
    content.setDtvAccountList(list);
    response.setContent(content);
    return helper.getAccountStatus(response);
}

助手类

public AccountResponse getAccountStatus(AccessIDSearchResponse accessIDResponse) {
    AccountResponse accountResponse = null;
    AccountRequest request = new AccountRequest();
    Account account = new Account();
    account.setCustomerID(accessIDResponse.getContent().getDtvAccountList().get(0).getAccountNumber());
    request.setAccount(account);
    String response = dtvnClients.callandGetDtvnStatus(request);
    System.out.println("Response is--->" + response);
    if (!Utility.isEmpty(response)) {
        accountResponse = JqUtil.runJqQueryAndGetString(".content.accountResponse", response,
                AccountResponse.class);
        if (!Utility.isEmpty(accountResponse) && accountResponse.isSubscribable() &&
                !Utility.isEmpty(accountResponse.getAccountStatus()) &&
                accountResponse.getAccountStatus().equalsIgnoreCase("FREEVIEW")) {
            return accountResponse;
        } 
    }
    return accountResponse;
}

测试类

@Test(expected = ServiceException.class)
public void test_searchAccessID_3_sample() throws Exception {
    AccessIDSearchRequest request = new AccessIDSearchRequest();
    CommonData commonData = new CommonData();
    commonData.setAppName("IDSE");
    commonData.setLoginId("qay_slid_sr1281");
    request.setCommonData(commonData);
    request.setSearchtype("accountId");
    request.setSearchvalue("qay_slid_sr1281");
    request.setMode("abc");

    SearchAccessIdContent content = new SearchAccessIdContent();
    AccountResponse accountResponse = new AccountResponse();
    accountResponse.setAccountStatus("Success");
    accountResponse.setSubscribable(true);

    Mockito.when(helper.getAccountStatus(accessIDResponse)).thenReturn(accountResponse);
    Mockito.when(service.checkAccountStatus(request)).thenReturn(accountResponse);

    service.searchAccessID(header, request);
}

注意:在代码中,有一处 "Sucess" 的拼写错误,已在翻译过程中修正。

英文:

From below piece of code I am not able to mock checkAccountStatus and its coming as null. What changes do I need to do to resolve this issue?

Class

public AccessIDSearchResponse searchAccessID(AccessIDSearchRequest accessIDRequest) {
		String[] productTypes = accessIDRequest.getProductTypes();
				AccountResponse actResponse = checkAccountStatus(accessIDRequest);
				System.out.println(&quot;Response is----&gt;&quot;+JsonService.getJsonFromObject(actResponse));
				if (accessIDRequest.getSearchtype().equalsIgnoreCase(&quot;accountId&quot;) &amp;&amp; !Utility.isEmpty(actResponse)
						&amp;&amp; !&quot;FREEVIEW&quot;.equalsIgnoreCase(actResponse.getAccountStatus())) {
					errorHandler.error(ErrorMessages.EPO_EXISTINGTV_ERR_07, ErrorMessages.ACCESS_ID_NOT_FOUND);
			}
}

public AccountResponse checkAccountStatus(AccessIDSearchRequest request) {
			AccessIDSearchResponse response = new AccessIDSearchResponse();
			SearchAccessIdContent content = new SearchAccessIdContent();
			DTVNAccountDetails accountDetails = new DTVNAccountDetails();
			accountDetails.setAccountNumber(request.getSearchvalue());
			List&lt;DTVNAccountDetails&gt; list = new ArrayList&lt;&gt;();
			list.add(accountDetails);
			content.setDtvAccountList(list);
			response.setContent(content);
			return helper.getAccountStatus(response);
	}

Helper

public AccountResponse getAccountStatus(AccessIDSearchResponse accessIDResponse) {
		AccountResponse accountResponse = null;
			AccountRequest request = new AccountRequest();
			Account account = new Account();
			account.setCustomerID(accessIDResponse.getContent().getDtvAccountList().get(0).getAccountNumber());
			request.setAccount(account);
			String response = dtvnClients.callandGetDtvnStatus(request);
			System.out.println(&quot;Response is---&gt;&quot;+response);
			if (!Utility.isEmpty(response)) {
				accountResponse = JqUtil.runJqQueryAndGetString(&quot;.content.accountResponse&quot;, response,
						AccountResponse.class);
				if (!Utility.isEmpty(accountResponse) &amp;&amp; accountResponse.isSubscribable()
						&amp;&amp; !Utility.isEmpty(accountResponse.getAccountStatus())
						&amp;&amp; accountResponse.getAccountStatus().equalsIgnoreCase(&quot;FREEVIEW&quot;)) {
					return accountResponse;
				} 
			}
		return accountResponse;
	}

Test Class

@Test(expected = ServiceException.class)
	public void test_searchAccessID_3_sample() throws Exception {
		AccessIDSearchRequest request = new AccessIDSearchRequest();
		CommonData commonData = new CommonData();
		commonData.setAppName(&quot;IDSE&quot;);
		commonData.setLoginId(&quot;qay_slid_sr1281&quot;);
		request.setCommonData(commonData);
		request.setSearchtype(&quot;accountId&quot;);
		request.setSearchvalue(&quot;qay_slid_sr1281&quot;);
		request.setMode(&quot;abc&quot;);

		SearchAccessIdContent content = new SearchAccessIdContent();
		AccountResponse accountResponse = new AccountResponse();
		accountResponse.setAccountStatus(&quot;Sucess&quot;);
		accountResponse.setSubscribable(true);

		Mockito.when(helper.getAccountStatus(accessIDResponse)).thenReturn(accountResponse);
		Mockito.when(service.checkAccountStatus(request)).thenReturn(accountResponse);

		service.searchAccessID(header, request);
	}

答案1

得分: 1

你的模拟配置不正确。

当你调用:

service.searchAccessID(header, request);

它会触发底层调用:

checkAccountStatus(request);

(该调用已被正确模拟并返回accountResponse),但是这个调用会实例化它的结果对象,因此你的第一个模拟永远不会被触发。

将你的第一个模拟更改为更宽松的方式可能会解决你的问题:

Mockito.when(helper.getAccountStatus(any(AccessIDSearchResponse.class))).thenReturn(accountResponse);

说实话,你的代码很难进行测试,因为你在各个地方都实例化了太多的对象。如果将来你重构了某些内容,使用模拟将会很麻烦。如果我是你,我会使用TDD方法重写这部分代码,并倾向于使用更可测试的模式。

英文:

Your mocks are not properly configured.

When you call

 service.searchAccessID(header, request);

it was make the underlying call

checkAccountStatus(request);

(which is correctly mocked and returns accountResponse), but this one does instanciate its result object, so your first mock will never be triggered.

Updating your first mock to something more permissive will probably fix your problem

Mockito.when(helper.getAccountStatus(any(AccessIDSearchResponse.class))).thenReturn(accountResponse);

To be honest, your code is hardly testable because you instanciate too many objects everywhere. Going for mocks here will be a pain in the future when you refactor something. If I were you I would rewrite this piece of code using a TDD approach and favorizing more testable patterns.

huangapple
  • 本文由 发表于 2020年7月25日 15:21:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63085549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定