Исключение при приведении ответа API - PullRequest
0 голосов
/ 16 октября 2018

enter image description here

Возникла проблема при приведении ответа API в модульном тесте для тестирования вызова API.

Я использую строку ниже для сравненияКод состояния ответа.

Assert.Equal(((int)eResp.Warn), ((ApiResponse)((ObjectResult)response).Value).StatusCode);

Я использую нижнюю строку для сравнения сообщения проверки.

Assert.Equal("Please enter a unique Name.", ((ApiResponse)((ObjectResult)response).Value).Message);

Ниже строки возвращает ответ от контроллера

 return Ok(new { Response = GetWarning(Warningmessage, MessageType) });

Возвращает метод GetWarningответ следующий:

return new ApiResponse((int)HttpStatusCode.Accepted, warningMessage, MessageType);

Но я получаю сообщение об ошибке "Invalid cast".Прикреплен скриншот объекта ответа

enter image description here

Как правильно разыграть и решить эту проблему?

1 Ответ

0 голосов
/ 18 октября 2018

В вашем контроллере вы делаете это:

return Ok(new { Response = GetWarning(Warningmessage, MessageType) });

Это заставляет контроллер обернуть ваш ответ дополнительным объектом "Response", подобным этому:

{
    "response": {
        "statusCode": ...
        "message": ...
        "messageType": ...
    }
}

ПРИМЕЧАНИЕ:Поля StatusCode, Message и MessageType являются свойствами вашего ApiResponse класса.

Но когда вы получаете доступ к ответу в своем тесте, вы пытаетесь получить к нему доступ как ApiResponse, но, из-за дополнительного поля Response оно не может десериализовать его.

Способ исправить это - изменить оператор возврата вашего контроллера на:

return Ok(GetWarning(Warningmessage, MessageType));

Это изменит форматОтвет JSON на:

{
    "statusCode": ...,
    "message": ...
    "messageType": ...
}

Теперь тип возвращаемого значения вашего метода контроллера (который является свойством response.Value) - OkObjectResult, что означает, что вы можете изменить свои тесты, чтобы потреблять меньше приведения:

Assert.Equal(((int)eResp.Warn), ((ApiResponse)response.Value).StatusCode);
Assert.Equal("Please enter a unique Name.", ((ApiResponse)response.Value).Message);

Теперь нам не нужно приводить объект response, поскольку он уже является OkObjectResult, у которого есть свойство Value.

EDIT

Если вам нужно сохранить обертку { Response: ... }, вам следует использовать класс дляо это.Я бы реорганизовал существующие классы так:

например

public class ApiResponse
{
    public Response Response { get; set; }
}

public class Response
{
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string MessageType { get; set; }
}

И в вашем контроллере вы сделаете следующее:

return Ok(new ApiResponse{ Response = GetWarning(...) });

Это вернетследующий JSON:

{
    "response": {
        "statusCode": 201,
        "message": "All good"
        "messageType: ...
    }
}

И теперь вы можете использовать классы, которые мы определили в наших тестах для проверки контроллера:

var result = controller.Get();   // this is your controller call

var apiResponse = result.Value as ApiResponse;

Assert.AreEqual(201, apiResponse.Response.StatusCode);
Assert.AreEqual("All good", apiResponse.Response.Message);

ПРИМЕЧАНИЕ. Добавление дополнительного слоя в ваш контроллер возвращаетМетод хорош, если вы просто отправляете результат чему-то, что обрабатывает JSON простым способом.К сожалению, модульным тестам C # нужен сильный тип, то есть класс, чтобы можно было десериализовать ответ и ссылаться на свойства в тесте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...