gpt4 book ai didi

java - 在when().thenReturn()返回的对象上调用方法

转载 作者:行者123 更新时间:2023-12-01 17:31:56 26 4
gpt4 key购买 nike

<小时/>

经过大量研究,我没有在 Java 中的 JUnits 中找到这个问题的答案。

我想要做的是:对when().thenReturn(object)调用返回的对象调用一些方法。

例如:

public boolean checkUpdate(String str, String endStr){
GetEndpointRequest geaReq = new
GetEndpointRequest().withEndpointArn(endpointArn);
GetEndpointResult geaRes = amazonSNS.getEndpointAttributes(geaReq);


return !geaRes.getAttributes().get("Token").equals(token) || !geaRes.getAttributes().get("Enabled").equalsIgnoreCase("true");
}

这是测试方法:

import com.amazonaws.services.sns.model.GetEndpointAttributesRequest;
import com.amazonaws.services.sns.model.GetEndpointAttributesResult;

@Tested
AmazonSNSRegistrationService service= new AmazonSNSRegistrationService();
service.amazonSNS = mock(AmazonSNS.class);

@Test
public void checkUpdateTest(){
String pushToken = "dxbv1fwJYIo";
String strToken = "";
String strEnabled = "";
String endPointArn = "";

Map<String, String> jsonBody = new HashMap<String, String>();
jsonBody.put("Token", "");
jsonBody.put("enabled", "");


GetEndpointAttributesRequest getEndpointReq =mock(GetEndpointAttributesRequest.class);
GetEndpointAttributesResult getEndpointRes =mock(GetEndpointAttributesResult.class);
getEndpointRes.setAttributes(jsonBody);

when(service.amazonSNS.getEndpointAttributes(getEndpointReq)).thenReturn(getEndpointRes);

when(getEndpointRes.getAttributes()).thenReturn(jsonBody);
when(getEndpointRes.getAttributes().get(strToken)).thenReturn("");
when(getEndpointRes.getAttributes().get(strEnabled)).thenReturn("");
amazonSNSRegistrationService.checkUpdate(pushToken, endPointArn);
}

我在 checkUpdate() 方法中遇到 NullPointerException - “return !geaRes.getAttributes().get("Token").equals(token)"。

因为,geaRes 为空。

如何解决这个问题?

添加另一个简单的示例,我在其中遇到此问题:

AmazonSNSRegistrationSerice.java:

public boolean deletePlatformApplicationArn(String deviceId, String appId){
boolean isArnDeleted = false;
try {
DeleteEndpointRequest deleteEndpointReq = new DeleteEndpointRequest().withEndpointArn(appId);
DeleteEndpointResult result = amazonSNS.deleteEndpoint(deleteEndpointReq);
if (result.getSdkHttpMetadata().getHttpStatusCode() == HttpStatus.SC_OK) {
AWSUtil.deleteArnEndpoint(deviceId, appId);
isArnDeleted = true;
}

} catch (Exception e) {

ErrorLogEventHelper.logErrorEvent(this.getClass().getName(), "Exception while deleting AWS ARN (endpoint)" + e.getMessage(), "deletePlatformApplicationArn", e, ErrorLogEvent.ERROR_SEVERITY);
}
return isArnDeleted;
}

AmazonSNSRegistrationSericeTest.java:

@Test
public void deletePlatformApplicationArnTest(){
String appId = "arn:aws:sns";
String deviceId = "dev_1";
DeleteEndpointRequest deleteEndpointReq = mock(DeleteEndpointRequest.class);
DeleteEndpointResult result = mock(DeleteEndpointResult.class);


when(amazonSNSRegistrationService.amazonSNS.deleteEndpoint(deleteEndpointReq)).thenReturn(result);

SdkHttpMetadata metadata = mock(SdkHttpMetadata.class);
when(result.getSdkHttpMetadata()).thenReturn(metadata);
when(result.getSdkHttpMetadata().getHttpStatusCode()).thenReturn(HttpStatus.SC_OK);

amazonSNSRegistrationService.deletePlatformApplicationArn(deviceId, appId);
}

if(result.getSdkHttpMetadata()) 中的结果对象再次变为 NULL。

最佳答案

首先,您尝试从 JsonMap 中获取空值:

@Test
public void checkUpdateTest(){
String strToken = "";
.
.
.
when(getEndpointRes.getAttributes().get(strToken)).thenReturn("");
// so what you ask here is this:
when(getEndpointRes.getAttributes().get("")).thenReturn("");
// this should probably be "Token"
when(getEndpointRes.getAttributes().get("Token")).thenReturn("");
}

接下来的事情是,JsonMap 是一个真实的对象,而不是一个模拟对象,因此您不需要调用 when(getEndpointRes.getAttributes().get(strToken)).thenReturn(""); 因为你的 jsonmap 将返回正确的值。

然后,不需要此调用,因为您的 getEndpointRes 是一个模拟。这就是为什么你使用when().thenX()语法

    getEndpointRes.setAttributes(jsonBody);

要解决您的 NPE 问题,请尝试以下操作:

// imports...

@Tested
AmazonSNSRegistrationService service= new AmazonSNSRegistrationService();

@Test
public void checkUpdateTest(){
// directly mock the amazonsns here
AmazonSNS amazonSNS = mock(AmazonSNS.class);
service.amazonSNS = amazonSNS;

String pushToken = "dxbv1fwJYIo";
String endPointArn = "";

// maybe mock them aswell
Map<String, String> jsonBody = new HashMap<String, String>();
jsonBody.put("Token", "");
jsonBody.put("enabled", "");


// deleted the mocked request. You don't need it in this case as your service contructs it by itself
GetEndpointAttributesResultgetEndpointRes getEndpointRes = mock(GetEndpointAttributesResult.class);
getEndpointRes.setAttributes(jsonBody);

// directly use the mocked object and react on any() as getEntpointReq never will be present in your service!
when(amazonSNS.getEndpointAttributes(any())).thenReturn(getEndpointRes);

when(getEndpointRes.getAttributes()).thenReturn(jsonBody);
amazonSNSRegistrationService.checkUpdate(pushToken, endPointArn);
// do some further assertments
}

您似乎试图模拟不需要模拟的事物以及模拟在您的服务中生成的事物。如果您在尝试测试的类中遇到 NPE,则应该正确调试您的测试。在您的情况下,模拟似乎不正确,因此真实对象调用会导致 NPE

在你的第二个例子中,这似乎是同样的问题。您尝试从模拟返回一些内容,该模拟可能是在您的 amazonSNSRegistrationService 内创建的。如果模拟的 deleteEndpointReq 不属于类的一部分,那么它应该如何返回任何值?您可以简单地创建模拟,但它与您的服务内部创建的对象不同!

毕竟你应该添加一些断言。我在这里看到的测试仅在被测试的类因像您的情况这样的错误而失败时才会失败。但缺少一些基本断言。我个人使用AAA pattern用于单元测试。

关于java - 在when().thenReturn()返回的对象上调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61103752/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com