XUnit InmemoryDB debug tests pass fail when ran

33 Views Asked by At

I have a static startup member which is used by both production and test projects which injects a context. Upon the test project this uses an inmemory db

I am writing an integration type test which calls the repos to add and then edit the items.

 [Fact]
 public void AddEditBusiness()
 {
     var repo = app.Services.GetService<IBusinessRepo>();
     var BusinessTypeRepo = app.Services.GetService<IBusinessTypesRepo>();

     var ret = repo.Add(new AddBusinessRequest()
     {
         DateCreated = DateTime.Now,
         Name = "Test1",
         NationWide = true,
         State = true,
         BusinessTypes = new List<AddBusinessTypesRequest>()
         {
             new AddBusinessTypesRequest() { BusinessTypeID = 1 },
             new AddBusinessTypesRequest() {BusinessTypeID = 2 }
         }
     });

     Task.WaitAll(ret);

     var AddRes = ret.Result;

     var edit = repo.Edit(new EditBusinessRequest()
     {
         BusinessID = AddRes.BusinessID,
         Name = "EditTest1",
         NationWide = false,
         State = true,
         DateCreated = AddRes.DateCreated
     });

     Task.WaitAll(edit);

     var editRes = edit.Result;

     Assert.Equal(editRes.BusinessID, AddRes.BusinessID);
     Assert.Equal("EditTest1", editRes.Name);
     Assert.Equal(false, editRes.NationWide);
     var btTask = BusinessTypeRepo.GetAllBursinessTypeForBusiness(new BusinessIDRequest()
     {
         BusinessID = editRes.BusinessID
     });

     Task.WaitAll(btTask);

     var bt = btTask.Result;

     Assert.True(bt.Count == 2);
 }

I have tried a combination of using async and non async and Task.Wait

The problem is it fails when running the test but passes when debugging - even with no breakpoints! I think I know what is happening - I think the context is being disposed and therefore losing the item when running, but if that's the case why does it pass when debugging. The error I am receiving is upon the edit part - it cannot find the record to edit. I have even tried putting Task.Delay(2000) thinking it was a race condition.

With that in mind I have tried setting the test context to be a singleton, transient and scoped. At the minute it feels like I am just trying stuff as I do not understand why it fails when running but passes when debugging.

Any help would be greatly appreciated.

1

There are 1 best solutions below

0
Trabumpaline On

I followed this post and it all made sense:

Can't get updated data across multiple DbContext with the same InMemory Db

Modified the interfaces for the repositories so they also inherit from IDisposable and set the scope of the test.

[Fact]
        public async void AddEditBusiness2()
        {
            using (var repo = app.Services.GetService<IBusinessRepo>())
            {
                var AddRes = await repo.Add(new AddBusinessRequest()
                {
                    DateCreated = DateTime.Now,
                    Name = "Test1",
                    NationWide = true,
                    State = true,
                    BusinessTypes = new List<AddBusinessTypesRequest>()
                {
                    new AddBusinessTypesRequest() { BusinessTypeID = 1 },
                    new AddBusinessTypesRequest() {BusinessTypeID = 2 }
                }
                });

                var editRes = await repo.Edit(new EditBusinessRequest()
                {
                    BusinessID = AddRes.BusinessID,
                    Name = "EditTest1",
                    NationWide = false,
                    State = true,
                    DateCreated = AddRes.DateCreated
                });

                using (var BusinessTypeRepo = app.Services.GetService<IBusinessTypesRepo>())
                {
                    var bt = await BusinessTypeRepo.GetAllBursinessTypeForBusiness(new BusinessIDRequest()
                    {
                        BusinessID = editRes.BusinessID
                    });
                    Assert.True(bt.Count == 2);
                    Assert.Equal(editRes.BusinessID, AddRes.BusinessID);
                    Assert.Equal("EditTest1", editRes.Name);
                    Assert.False(editRes.NationWide);
                }
            }
        }