Проверка состояния модели в модульных тестах
Я пишу unit test для такого контроллера:
public HttpResponseMessage PostLogin(LoginModel model)
{
if (!ModelState.IsValid)
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
модель выглядит следующим образом:
public class LoginModel
{
[Required]
public string Username { set; get; }
[Required]
public string Password { set; get; }
}
Тогда у меня есть unit test, как этот:
[TestMethod]
public void TestLogin_InvalidModel()
{
AccountController controller = CreateAccountController();
...
var response = controller.PostLogin(new LoginModel() { });
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
}
На самом деле ModelState проверяется... что странно для меня, поскольку оба поля необходимы...
Может ли кто-нибудь посоветовать?
Ответы
Ответ 1
Причина, по которой состояние модели действительна, заключается в том, что при новом обновлении контроллера создается новое состояние модели. Web API не выполняет привязки параметров для вас здесь, поэтому у него даже нет возможности добавлять ошибки состояния модели.
Если вы хотите сохранить это как unit test, тогда вы должны сами добавить ошибки состояния модели и проверить, что происходит.
Если вы хотите проверить, что состояние модели недействительно в реальном запросе, я рекомендую вам прочитать это сообщение в блоге:
http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx
и попробуйте протестировать сервер с памятью. Одна из незначительных замечаний для вашего случая заключалась бы в том, что вы можете использовать StringContent вместо ObjectContent в запросе, чтобы убедиться, что веб-API пытается десериализовать и правильно привязать тело.
Ответ 2
TL; DR
Если вы не хотите читать всю статью, предоставленную Youssef, и хотите быстро решить, как заставить ModelState.IsValid вернуть false. Сделай это.
[TestMethod]
public void TestLogin_InvalidModel()
{
AccountController controller = CreateAccountController();
// new code added -->
controller.ModelState.AddModelError("fakeError", "fakeError");
// end of new code
...
var response = controller.PostLogin(new LoginModel() { });
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
}
Теперь я могу представить, что CreateAccountController() выглядит примерно так: минимум →
return new AccountApiController()
{
Request = new HttpRequestMessage(),
Configuration = new HttpConfiguration()
};
Надеюсь, что это даст быстрый ответ для этих поисковых запросов:)
Ответ 3
Как упоминалось ранее, вам нужны интеграционные тесты для проверки ModelState. Итак, с Asp.Net Core я решил этот вопрос, чтобы добавить простое решение для интеграции тестов с Asp.Net Core и проверки ModelState
Добавьте пакет Microsoft.AspNetCore.TestHost
, и вы сможете отправлять запросы так просто:
var server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
var client = server.CreateClient();
var model = new { Name = String.Empty };
var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");
var result = await client.PostAsync("/api/yourApiEndpoint", content);
result.StatusCode.Should().Be(HttpStatusCode.BadRequest);
Вы можете найти больше об этом здесь:
http://asp.net-hacker.rocks/2017/09/27/testing-aspnetcore.html
Надеюсь, это поможет.
Ответ 4
Я использовал следующее для проверки состояния модели в модульном тесте Visual studio 2017, С#, NET 4.x.x
[TestMethod]
public void TestYourValidationModel()
{
var configuration = new HttpConfiguration();
configuration.Filters.Add(new ValidateModelAttribute());
// Get the quote
var controller = new YourController
{
Request = new HttpRequestMessage(),
Configuration = configuration
};
var request = YourRequestObject;
controller.Request.Content = new ObjectContent<YourRequestType>(
request, new JsonMediaTypeFormatter(), "application/json");
controller.Validate(request);
Assert.IsTrue(controller.ModelState.IsValid, "This must be valid");
}
Пример для запроса в формате JSON. Замените YourController на имя вашего контроллера, а YourRequesType на тип объекта вашего запроса.
Это дает вам возможность протестировать вашу модель для проверки без обращения в сервис.