Base solution for your next web application
Open Closed

Unit Test Error DBContext disposed #1158


User avatar
0
andis created
......
{
    public class LookUpTableService_Tests : AppTestBase
    {
        private readonly ILookUpTableService _lookUpTableService;
        private readonly IRepository<LookUpTable, Guid> _repositoryLookUpTable;
        private readonly IRepository<LookUpTableLine, Guid> _repositoryLookUpTableLine;
        public LookUpTableService_Tests()
        {
            _lookUpTableService = Resolve<ILookUpTableService>();
            _repositoryLookUpTable = Resolve<IRepository<LookUpTable, Guid>>();
            _repositoryLookUpTableLine = Resolve<IRepository<LookUpTableLine, Guid>>();
        }
        [Fact]
        public async Task Test_GetValue()
        {
            LoginAsDefaultTenantAdmin();
            await UsingDbContext(async context =>
            {
                LookUpTable lookUpTable = new LookUpTable();
                lookUpTable.Name = "1";
                lookUpTable.Active = true;
                    await _repositoryLookUpTable.InsertAsync(lookUpTable);
                    LookUpTableLine line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 1;
                    line.Value = 10;
                    line.Description = 1.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 2;
                    line.Value = 20;
                    line.Description = 2.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 3;
                    line.Value = 30;
                    line.Description = 3.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 4;
                    line.Value = 40;
                    line.Description = 4.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 5;
                    line.Value = 50;
                    line.Description = 5.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    lookUpTable = new LookUpTable();
                    lookUpTable.Name = "2";
                    lookUpTable.Active = true;
                    await _repositoryLookUpTable.InsertAsync(lookUpTable);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 6;
                    line.Value = 60;
                    line.Description = 6.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 7;
                    line.Value = 70;
                    line.Description = 7.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 8;
                    line.Value = 80;
                    line.Description = 8.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 9;
                    line.Value = 90;
                    line.Description = 9.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                    line = new LookUpTableLine();
                    line.LookUpTableId = lookUpTable.Id;
                    line.LookUpValue = 10;
                    line.Value = 100;
                    line.Description = 10.ToString();
                    await _repositoryLookUpTableLine.InsertAsync(line);
                try
                {
                    lookUpTable = _repositoryLookUpTable.FirstOrDefault(m => m.Name == "1");
                    Assert.Equal(4, _lookUpTableService.GetValue(lookUpTable, (decimal)4.5)); //Error on GetValue
                    lookUpTable = _repositoryLookUpTable.FirstOrDefault(m => m.Name == "2");
                    Assert.Equal(0, _lookUpTableService.GetValue(lookUpTable, (decimal)4.5));
                    Assert.Equal(10, _lookUpTableService.GetValue(lookUpTable, 14));
                }
                catch(Exception ex)
                {
                    throw ex;
                }
            });
        }
    }
}

GetValue code

public decimal GetValue(LookUpTable lookUpTable, decimal lookUpValue)
        {
            LookUpTableLine line = RepositoryLookUpTableLine.GetAll().Where(m => m.LookUpTable == lookUpTable && m.LookUpValue < lookUpValue).OrderByDescending(m => m.LookUpValue).FirstOrDefault();
            if (line == null)
                return 0;
            return line.Value;
        }

Error Message: The operation cannot be completed because the DbContext has been disposed. Stack Trace: at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source) at Nascence.HaermesCLX.DomainServices.Class.LookUpTableService.GetValue(LookUpTable lookUpTable, Decimal lookUpValue) in C:\Development\CLxCoreApp\Nascence.HaermesCLX.Core\DomainServices\Class\LookUpTableService.cs:line 29 at Nascence.HaermesCLX.Tests.DomainServices.LookUpTableService_Tests.<<Test_GetValue>b__4_0>d.MoveNext() in C:\Development\CLxCoreApp\Tests\Nascence.HaermesCLX.Tests\DomainServices\LookUpTableService_Tests.cs:line 101

Is there anything wrong with my code? why it keep getting this error? i tried to change it to non-awaitable.. still got same error


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Domain services are not transactional by default. You can resolve IUnitOfWorkManager in your test class and then start a transaction by yourself.

  • User Avatar
    0
    andis created

    Do you mind to explain why my unit test need a transactional? why lack of transactional will cause me this error?

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    It's actually not related to transactions. It's about Unit Of Work system of the framework. When you are using repository's GetAll() method, your code should run in a UOW (which provides the database connection), because GetAll() returns IQueryable which is executed as deferred and needs to an open database connection when the Queryable is executed (FirstOrDefault in your code).

    Simple solution: Change your GetValue method definition like that:

    [UnitOfWork] public virtual decimal GetValue(LookUpTable lookUpTable, decimal lookUpValue)

    To understand UOW better, I suggest you to read the documentation (<a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work">http://www.aspnetboilerplate.com/Pages/ ... it-Of-Work</a>), especially the GetAll() part: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocRepositoryGetAll">http://www.aspnetboilerplate.com/Pages/ ... toryGetAll</a>