2017-04-05 1 views
0

ASPNETコアプロジェクトでは、データ検証ロジックが正常に動作することを確認するユニットテストをいくつか作成しようとしています。ユニットテストコントローラモデルの検証AspNetCore

私のコントローラは非常に簡単です:私は、テスト対象のコントローラとして_myControllerオブジェクトを設定しますテストの基本クラスを使用しています

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

    _dataItemSaver.SaveData(item); 
} 

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

DataItemが必要な属性(この例ではProp3)が不足している場合でも、ユニットテストを実行しているときにModelState.IsValidtrueですが、私が見つけています。同じ入力を使用してWeb経由でコントローラをテストする場合、検証は正常に機能します(ModelState.IsValidの場合はfalseを返します)。

単体テストからモデルステート検証用のASPNETコアロジックを正しくトリガするにはどうすればよいですか?

+1

'ModelState'が無効な場合にあなたが本当に例外をスローするつもりはないが、あなたは?を参照してください。 –

+0

グローバル例外フィルタで例外を処理し、すべてのエラー処理と書式設定を同じ場所に保持しました。チェックをフィルタに移動してグローバルに適用できますが、例外をスローしてグローバルフィルタで処理する方法を保ちます。 –

+0

真剣に?ユーザーが検証エラーを訂正できるように、メソッドはビューを戻す必要があります。 –

答えて

4

ASP.NETコアによる統合テスト(https://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing)をご覧ください。これは、テストコンテキストでアプリケーションをホストし、パイプライン全体をテストする非常に簡単な方法です。モデル状態の検証のみですので、あなたが手動でモデル状態のエラーをシミュレートする必要があり、純粋なユニットテストを行いたい場合は

_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); 
+0

ありがとう、これは私が探していたものです! –

1


としては、あなたの試験方法でこのような何かを行うことがマニュアルに記載されています実行時にトリガーされます。

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

詳細についてhttps://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing

関連する問題