abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.8k stars 3.41k forks source link

About ABP vnext unit test error Cannot access a disposed context instance #17746

Closed zhangxianchengvip closed 1 year ago

zhangxianchengvip commented 1 year ago

I am writing unit tests based on ABP vnext, but it encountered an error. The following is the relevant code

DomainService:

    public async Task<Terminal> Create(string sn)
    {
        var any = await _repository.AnyAsync(new TerminalSnEqualSpec(sn));

        if (any)
        {
            throw new UserFriendlyException($"设备'{sn}'已存在!");
        }

        Terminal terminal = new(GuidGenerator.Create(), sn);

        return await _repository.InsertAsync(terminal, true);
    }

UnitTest:

public class TerminalManager_Tests : DeviceDomainTestBase
{
    private readonly TerminalManager _manager;

    public TerminalManager_Tests()
    {
        _manager = GetRequiredService<TerminalManager>();
    }

    [Fact]
    public async Task Should_CreateAsync()
    {
        string sn = "string";

        Terminal terminal = await _manager.Create(sn); ;
        terminal.ShouldNotBeNull();

        //await WithUnitOfWorkAsync(async () =>
        //{
        //    Terminal terminal = await _manager.Create(sn); ;
        //    terminal.ShouldNotBeNull();
        //});
    }
}

image

When the code is executed to var any=await_ Repository AnyAsync (new TerminalSnEqualSpec (sn)); An error will occur System.ObjectDisposedException : Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'DeviceDbContext'.

realLiangshiwei commented 1 year ago

Try to use virtual.

[UnitOfWork]
public virtual Task<Terminal> Create(string sn)
zhangxianchengvip commented 1 year ago

Try to use virtual.

[UnitOfWork]
public virtual Task<Terminal> Create(string sn)

I tried using the following code

    await WithUnitOfWorkAsync(async () =>
    {
        Terminal terminal = await _manager.Create(sn); ;
        terminal.ShouldNotBeNull();
    });