question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Broke all our test cases: Abp.AbpException : Did not call Complete method of a unit of work.....

See original GitHub issue

Hi Halil,

  • ABP 2.1.2

We have been running ABP in our unit tests as follows for a long time now, but this behavior started happening as soon as we upgraded from 2.0 to 2.1.2. And unfortunately rolling back is not an option at the moment so I am looking for a fix or work around ASAP.

We use NUnit for all our unit testing and have our test fixtures structured as follows:

/// <summary>
///     Adapter class to work with the ABP base test class, to ensure the IocManager is correctly
///     instantiated.
/// </summary>
public class AbpApplicationServiceTestsAdapter : OzAbpTestsAdapterBase<AbpApplicationServiceTestsAdapterModule>
{
    /// <summary>
    ///     Class constructor.
    /// </summary>
    public AbpApplicationServiceTestsAdapter()
    {
        //Ensure all the AutoMapper mappings are in place
        OzCpAutoMapperConfig autoMapperConfig = new OzCpAutoMapperConfig();
        autoMapperConfig.Configure();

        //Ensure that we have applied all the DB migrations
        string connString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;

        DatabaseMigrationsManager dbMigrationsManager = new DatabaseMigrationsManager(connString, DbEnvironmentKindEnum.Automation);
        DatabaseUpgradeResult dbMigrationResult = dbMigrationsManager.Process();
        if (!dbMigrationResult.Successful)
            throw dbMigrationResult.Error;
    }
}

[TestFixture]
public class OzCpApiServiceTests : OzTestsBase
{
    private AbpApplicationServiceTestsAdapter _AbpApplicationTestsAdapter;
    private IOzCpApiService _ApiService;
    private IUnitOfWorkCompleteHandle _UnitOfWork;
    private IUnitOfWorkManager _UnitOfWorkManager;

    /// <summary>
    ///     Called at the conclusion of all the unit tests.
    /// </summary>
    [OneTimeTearDown]
    public void DeInit()
    {
    }

    /// <summary>
    ///     Called at the commencement of all the unit tests.
    /// </summary>
    [OneTimeSetUp]
    public void Init()
    {
        //Spin up the adapter class to register all the necessary with the IocManager
        _AbpApplicationTestsAdapter = new AbpApplicationServiceTestsAdapter();

        //Create our reference to the reference port service
        _ApiService = _AbpApplicationTestsAdapter.LocalIocManager.Resolve<IOzCpApiService>();
    }

    /// <summary>
    ///     Called before each test.
    /// </summary>
    [SetUp]
    public void TestSetup()
    {
        //Ensure all interactions run within a transaction of their own so that our changes are not persisted to the test database
        _UnitOfWorkManager = _AbpApplicationTestsAdapter.LocalIocManager.Resolve<IUnitOfWorkManager>();
        _UnitOfWork = _UnitOfWorkManager.Begin(new UnitOfWorkOptions
                                               {
                                                   IsolationLevel = IsolationLevel.ReadUncommitted
                                               });
    }

    /// <summary>
    ///     Called after each test.
    /// </summary>
    [TearDown]
    public void TestTearDown()
    {
        //Clean up any manually resolved IoC instances
        _AbpApplicationTestsAdapter.LocalIocManager.Release(_ApiService);

        //Force our unit of work to roll back our transaction
        _UnitOfWork.Dispose();
    }
}

You can pretty much ignore the AbpApplicationServiceTestsAdapter asit just ensures that the AbpApplicationServiceTestsAdapterModule pulls in all the required ABP modules which ulitmately contain the services and repositories.

In essence our tests all run against a physical SQL Server database (we cannot mock as we need SP support etc.) but we make sure that each test runs within its own transaction. However today when running our unit tests I started getting:

TearDown : Abp.AbpException : Did not call Complete method of a unit of work. –TearDown at Abp.Domain.Uow.InnerUnitOfWorkCompleteHandle.Dispose()

So what this has meant is that transactions are not working as expected and I have data changes occurring in our Test DB when they should have been rolled back. I am also getting similair timeout issues as reported in #2217 but I figured that was related to my error above.

So can you advise whether:

  1. We have uncovered a bug? (We specifically don’t call .Complete() as we want to roll back the transaction)
  2. If not a bug then how I should deal with transactions for each test case so that it works “with ABP”?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:31 (31 by maintainers)

github_iconTop GitHub Comments

1reaction
hikalkancommented, Jul 3, 2017

The problem is tricky and related to implementation of AsyncLocal by .net. If you want to know more, you can read this issue (https://github.com/dotnet/corefx/issues/8681) which I have some comments and code samples.

In brief, if you set an ambient value (to callcontext or asynclocal) and return from the method, the value has gone! You begin UOW inside TestSetup then returning from this method and ambient UOW reference is lost. I know this is a strange behaviour and I could not find a way and Microsoft workers said this is by design. Anyway, after the test I requested, we can better understand if the problem is that.

0reactions
hikalkancommented, Jul 20, 2017

It can be related to AsyncLocal change but really I could not figure out what’s the exact difference.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Broke all our test cases: Abp.AbpException : Did not call ...
We have been running ABP in our unit tests as follows for a long time now, but this behavior started happening as soon...
Read more >
Unit Of Work not work properly in aspnetboilerplate app ...
Work on aspnetboilerplate, have following kind of code in app-service, Unit Of Work ... Complete() data already deleted from the database.
Read more >
Conventional Unit Of Work Methods
AspNet Boilerplate (ABP) is an open source and well-documented application framework. See the comprehensive tutorials of ABP for technical information.
Read more >
Bugs & Issues v4.4.X #1543 | Support Center | ABP Commercial
When I tried to run the .Web program for the first time. AbpException: Could not find the bundle file '/libs/abp/core/abp.css' for the bundle...
Read more >
Mastering ABP Framework
Halil will guide you on how to write unit and integration tests using ABP Framework easily. By the end of this book, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found