在一個ASPNET核心項目中,我試圖創建一些單元測試來驗證我的數據驗證邏輯是否正常工作。AspNetCore上的單元測試控制器模型驗證
我的控制器是非常簡單的:
[HttpPost]
[Route("Track")]
public void Track([FromBody] DataItem item)
{
if (!ModelState.IsValid) throw new ArgumentException("Bad request");
_dataItemSaver.SaveData(item);
}
我使用的是測試的基類,將建立_myController
對象作爲測試控制器。
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>();
}
測試也是非常簡單的:
[TestMethod]
public void Prop3Required()
{
// Arrange
var dataItem = new DataItem()
{
Prop1 = "Prop1",
Prop2 = "Prop2"
};
// Act & Assert
Assert.ThrowsException<ArgumentException>(() => _myController.Track(dataItem));
}
我發現雖然這ModelState.IsValid
是true
運行,即使我的DataItem
缺少必需的屬性的單元測試(Prop3
在這個例子中)時。當使用相同的輸入通過網絡測試控制器時,驗證工作是正確的(返回false
爲ModelState.IsValid
)。
如何從單元測試中正確觸發用於模型狀態驗證的ASPNET核心邏輯?
你不是真的要拋出一個異常時,'ModelState'是無效的,你見https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing? –
我做了,並在全局異常過濾器中處理異常,以保持所有錯誤處理和格式化在同一個地方。可以將支票移動到過濾器並全局應用,但會繼續拋出異常並將其處理到全局過濾器中。 –
認真嗎?您的方法應該返回視圖,以便用戶可以更正驗證錯誤。 –