вызов метода для объекта, возвращаемого методом when (). thenReturn () - PullRequest
0 голосов
/ 08 апреля 2020

Проведя много исследований, я не нашел ответа на этот вопрос в JUnits в java.

Что я хочу сделать: вызвать некоторый метод для объекта, возвращаемого when (). thenReturn (object) call.

например:

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");
}

А вот метод Test:

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);
}

Я получаю исключение NullPointerException в checkUpdate () метод в строке - "return! geaRes.getAttributes (). get (" Token "). equals (token)".

As, geaRes имеет значение null.

Как решить это?

Добавление еще одного простого примера, где я сталкиваюсь с этой проблемой:

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.

1 Ответ

0 голосов
/ 09 апреля 2020

Итак, во-первых, вы пытаетесь получить пустое значение из вашего 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 должен вернуть любое значение, если оно не является частью класса? Вы просто создаете макет, но это не тот же объект, который создается внутри вашего сервиса!

И в конце концов вам следует добавить некоторые утверждения. Тесты, которые я вижу здесь, терпят неудачу, только если тестируемый класс завершается с ошибкой, как в вашем случае. Но некоторые основные утверждения c отсутствуют. Я лично использую AAA шаблон для модульных тестов.

...