2017-07-07 3 views
0

NUnit、Shouldly、Entity Frameworkのメモリ内SQLiteデータベースを使用して統合テストを行っていて、データベース呼び出しを実行しないテストケースの2つにぶつかりました。 (実行を待つことはありません)。c#testing async task - テストケースがawaitを無視する - NullReferenceException

コントローラー:

[HttpPost("DeleteOrganisations")] 
public async Task<IActionResult> DeleteOrganisations([FromBody] DeleteOrganisationsModel model) 
{ 
    //Test case 2 fails here 
    if (model == null || !ModelState.IsValid) 
    { 
     return Ok(new GenericResultModel(_localizer["An_unexpected_error_has_occurred_Please_try_again"])); 
    } 

    List<OrganisationModel> organisations = (await _organisationService.GetOrganisations(model.OrganisationIds)).ToList(); 

    //Test case 3 fails here 
    if (organisations == null || organisations.Count == 0) 
    { 
     return Ok(new GenericResultModel(_localizer["Could_not_find_organisations"])); 
    } 

    StatusModel status = await _statusService.GetStatus(StatusTypeEnum.StatusType.Organisation, StatusEnum.Status.Removed); 

    if (status == null) 
    { 
     return Ok(new GenericResultModel(_localizer["Could_not_find_status"])); 
    } 

    foreach (OrganisationModel organisation in organisations) 
    { 
     organisation.StatusId = status.Id; 
    } 

    List<OrganisationModel> updatedOrganisations = (await _organisationService.UpdateOrganisations(organisations)).ToList(); 

    if (updatedOrganisations == null || updatedOrganisations.Count == 0) 
    { 
     return Ok(new GenericResultModel(_localizer["Could_not_remove_organisations"])); 
    } 

    if (updatedOrganisations.Count == 1) 
    { 
     return Ok(new GenericResultModel { Id = updatedOrganisations[0].Id }); 
    } 

    return Ok(new GenericResultModel { Count = updatedOrganisations.Count }); 
} 

試験:

[TestFixture] 
public class DeleteOrganisations : TestBase 
{ 
    private OrganisationController _organisationController; 

    [OneTimeSetUp] 
    public void OneTimeSetUp() 
    { 
     //Controller 
     _organisationController = new OrganisationController(null, Mapper, OrganisationService, StatusService, AuthenticationService); 

     //Object Mother 
     ObjectMother.InsertTestData(); 
    } 

    public static IEnumerable TestCases 
    { 
     get 
     { 
      yield return new TestCaseData(new DeleteOrganisationsModel { OrganisationIds = new List<int>() { 1 } }, 0, 1).SetName("DeleteOrganisations_Should_Delete_Data_When_OrganisationId_Exist"); 

      yield return new TestCaseData(new DeleteOrganisationsModel { OrganisationIds = null }, 0, 0).SetName("DeleteOrganisations_Should_Not_Delete_Data_When_Null"); 
      yield return new TestCaseData(new DeleteOrganisationsModel { OrganisationIds = new List<int>() { 2 } }, 0, 0).SetName("DeleteOrganisations_Should_Not_Delete_Data_When_OrganisationId_Not_Exist"); 
     } 
    } 

    [Test, TestCaseSource(nameof(TestCases))] 
    public async Task Test(DeleteOrganisationsModel model, int removedOrganisationCountBefore, int removedOrganisationCountAfter) 
    { 
     //Before 
     int resultBefore = Database.Organisation.Include(o => o.Status).Count(o => o.Status.Name == StatusEnum.Status.Removed.ToString()); 

     resultBefore.ShouldBe(removedOrganisationCountBefore); 

     //Delete 
     await _organisationController.DeleteOrganisations(model); 

     //After 
     int resultAfter = Database.Organisation.Include(o => o.Status).Count(o => o.Status.Name == StatusEnum.Status.Removed.ToString()); 

     resultAfter.ShouldBe(removedOrganisationCountAfter); 
    } 
} 

テストケース1つのパス

StatusModel status = await _statusService.GetStatus(StatusTypeEnum.StatusType.Organisation, StatusEnum.Status.Removed); 

ために呼び出され、その結果が待たれます。

テストケース2と3は、関数(if文)で待たれることはないため、失敗します。

メッセージ:System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンス に設定されていません。

私はおそらくどんな待つ文を実行して、新しいテスト機能のための非同期タスクをスキップしていない結果のために別のテストを作成することができますが、その後、私は言ってメッセージを得るでしょう

:このため

コールが待たれていない場合は、現在のメソッド の実行がコールが完了する前に継続されます。呼び出しの結果に 'await' 演算子を適用することを検討してください。

テストはおそらく失敗しますが、2つのテストと構文エラーの考えが似ていません。

あなたは何をしますか?

編集

例外:

Message: System.NullReferenceException : Object reference not set to an instance of an object. 

のStackTrace:

Test Name: DeleteOrganisations_Should_Not_Delete_Data_When_OrganisationId_Not_Exist 
Test FullName: MyProject.Test.Api.Administration.Organisation.DeleteOrganisations.DeleteOrganisations_Should_Not_Delete_Data_When_OrganisationId_Not_Exist 
Test Source: C:\Users\User\Documents\Visual Studio 2017\Projects\MyProject\MyProject.Test\Api\Administration\Organisation\DeleteOrganisations.cs : line 42 
Test Outcome: Failed 
Test Duration: 0:00:02.48 

Result StackTrace: at MyProject.Api.Controllers.Administration.OrganisationController.<DeleteOrganisations>d__8.MoveNext() in C:\Users\User\Documents\Visual Studio 2017\Projects\MyProject\MyProject.Api\Controllers\Administration\OrganisationController.cs:line 114 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at MyProject.Test.Api.Administration.Organisation.DeleteOrganisations.<Test>d__4.MoveNext() in C:\Users\User\Documents\Visual Studio 2017\Projects\MyProject\MyProjectTest\Api\Administration\Organisation\DeleteOrganisations.cs:line 49 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at NUnit.Framework.Internal.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(Object invocationResult) 
    at NUnit.Framework.Internal.Commands.TestMethodCommand.RunAsyncTestMethod(TestExecutionContext context) 
Result Message: System.NullReferenceException : Object reference not set to an instance of an object. 
+0

が、私は任意の例外の詳細が含まれていませんでした@Willが、私は例外とスタックトレース – Reft

+0

ない便利で、私の質問を編集しました情報?ハッハッハー。あなたの問題はここにあります: 'Organisation.DeleteOrganisations'。あなたはそのメソッドの中で何かを待っていて、それが何であれ例外をスローしています。 **これは、あなたのテスト方法**とはまったく関係ありません。 DeleteOrganizationsにブレークポイントを設定し、テストをデバッグし、nullを確認します。 – Will

+0

私はそれを言っていないふりをしましょう:) – Reft

答えて

1

手のひらを顔に当てる - 私はtestbaseでローカライザークラスを注入するのを忘れました。申し訳ありませんが、私の悪い人。

右ここにこの行:私はそれが有用な情報を持っていないと思うので

if (organisations == null || organisations.Count == 0) 
{ 
    return Ok(new GenericResultModel(_localizer["Could_not_find_organisations"])); 
}