Unit test controller model validation on AspNetCore

允我心安 提交于 2019-11-30 05:23:43

问题


In an ASPNET Core project I am trying to create some unit tests that would verify my data validation logic works fine.

My controller is very simple:

[HttpPost]
[Route("Track")]
public void Track([FromBody] DataItem item)
{
    if (!ModelState.IsValid) throw new ArgumentException("Bad request");

    _dataItemSaver.SaveData(item);
}

I am using a test base class that would set up the _myController object as the controller under test.

    public ControllerTestBase()
    {
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"buildversion.json", optional: true)
            .AddEnvironmentVariables();
        _config = builder.Build();

        var services = new ServiceCollection()
            .AddEntityFrameworkInMemoryDatabase()
            .AddDbContext<MyDbContext>(options =>
            {
                options.UseInMemoryDatabase();
            })
            .AddScoped<IDataItemSaver, DataItemSQLStorageService>()
            .AddScoped<MyController>()
            .Configure<MyConfig>(_config.GetSection(nameof(MyConfig)));

        services
            .AddMvc(mvcOptions =>
                {
                    mvcOptions.Filters.AddService(typeof(GlobalExceptionFilter), 0);
                });

        _additionalDISetupActions?.Invoke(services);

        _serviceProvider = services.BuildServiceProvider();

        _myController = _serviceProvider.GetService<MyController>();
    }

The test again is very simple:

    [TestMethod]
    public void Prop3Required()
    {
        // Arrange
        var dataItem = new DataItem()
        {
            Prop1 = "Prop1",
            Prop2 = "Prop2"
        };

        // Act & Assert
        Assert.ThrowsException<ArgumentException>(() => _myController.Track(dataItem));
    }

I am finding though that ModelState.IsValid is true when running a unittest even when my DataItem is missing required attributes (Prop3 in this example). When testing the controller through the web with the same input, the validation works correctly (returning false for ModelState.IsValid).

How do I properly trigger the ASPNET Core logic for modelstate validation from a unit test?


回答1:


You should take a look at Integration Testing with ASP.NET Core (https://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing), it is a very simple way to host your application in a test context and test your entire pipeline.
As explained in the documentation you could do something like this in your test method:

_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
_client = _server.CreateClient();
// Pass a not valid model 
var response = await _client.PostAsJsonAsync("Track", new DataItem());
Assert.IsFalse(response.IsSuccessStatusCode);



回答2:


If you want to do a pure unit test you need to manually simulate the model state error because the model state validation is only triggered during runtime.

_myController.ModelState.AddModelError("yourItemFieldHere", "Your validation type here");

See https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing for more detail



来源:https://stackoverflow.com/questions/43229338/unit-test-controller-model-validation-on-aspnetcore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!