Abp: Test with another DBContext

Created on 24 May 2019  路  17Comments  路  Source: abpframework/abp

How to adapt templates\mvc\test\MyCompanyName.MyProjectName.Application.Tests to be able to query an entity tied to another DbContext ? This another context is not Abp-related. Should I modify MyProjectNameApplicationTestModule ? Manage another SqliteConnection instance ? Call another context.DbContextOptions.UseSqlite ? How ? I'm a bit lost in the service configuration bits in MyProjectNameApplicationTestModule ...

question

Most helpful comment

I finally found how to do it. The missing piece was how to adapt the ConfigureInMemorySqlite method. Here's how I done it :

private void ConfigureInMemorySqlite(IServiceCollection services)
{
    _primarySqliteConnection 
        = CreateDatabaseAndGetConnection<PrimaryMigrationsDbContext>(
            options => new PrimaryMigrationsDbContext(options));
    _secondarySqliteConnection
        = CreateDatabaseAndGetConnection<SecondaryMigrationsDbContext>(
            options => new SecondaryMigrationsDbContext(options));

    services.Configure<AbpDbContextOptions>(options =>
    {
        options.Configure(context => { context.DbContextOptions
            .UseSqlite(
                context.ConnectionStringName == MyAppConsts.SecondaryConnectionStringName 
                    ? _secondarySqliteConnection
                    : _primarySqliteConnection ); });
    });
}

All 17 comments

I finally found how to do it. The missing piece was how to adapt the ConfigureInMemorySqlite method. Here's how I done it :

private void ConfigureInMemorySqlite(IServiceCollection services)
{
    _primarySqliteConnection 
        = CreateDatabaseAndGetConnection<PrimaryMigrationsDbContext>(
            options => new PrimaryMigrationsDbContext(options));
    _secondarySqliteConnection
        = CreateDatabaseAndGetConnection<SecondaryMigrationsDbContext>(
            options => new SecondaryMigrationsDbContext(options));

    services.Configure<AbpDbContextOptions>(options =>
    {
        options.Configure(context => { context.DbContextOptions
            .UseSqlite(
                context.ConnectionStringName == MyAppConsts.SecondaryConnectionStringName 
                    ? _secondarySqliteConnection
                    : _primarySqliteConnection ); });
    });
}

Thank you for sharing your solution.

Since I want to upgrade my Visual Studio solution to ABP 2.2.1 from 0.17, I restarted from the ground by downloading the new MVC template with abp-cli. Then I re-applied carefully my commits.

Now, the problem is that I encounter the following exception: System.InvalidOperationException : The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.. And in DbMigrator. And I would not be surprised to get this in the other projects of my solution too. For example, in tests, it seems that MyProjectTestBase.WithUnitOfWorkAsync(Func<Task> func) cannot handle entities linked to different DbContexts.

I am aware of the new per-module DbContext capability. But this secondary DbContext is intended to be used on the whole solution, like the default one. The two are defined in the same module: the EntityFramework one of the solution.

Update: After testing, I know now that this problem affects only tests running. DbMigrator and Web run ok.

Update 2: Solved by surrounding test code calling secondary DbContext with using (var uow = _unitOfWorkManager.Begin(requiresNew: true))

Hi all,

This solution helped me a little but still after am seeding data in the second database in memory, the injected context in AppServices or Repositories can not find data and DB in memory is empty!!. It seems that DI is injecting a new object of context not the same one used to seed data, any help ??

Thanks.

@Wello86 Did you try to build your in-memory test database inside a file instead? I used this approach several times to investigate sqlite db content.

Also, did you implement an IDataSeedContributor in your TestBase project? Is this the way you seed your additional seed data for test runs ?

Yes I used a file instead and found my content inside so this means insert is working. In test method itself the repository can not find the data. It is empty

I am just doing this in my class of testing

private readonly IRepository<MyEntity, Guid> _repository;

_repository= GetRequiredService>();

  var result = await _repository.GetListAsync();
            result.Count.ShouldBeGreaterThan(0);

with one DB it is working but when I splitted my App to 2 databases, it is working with the first but not the second

@Wello86 Maybe your UOW is not aware of new data. Did you try surrounding test code calling secondary DbContext with using (var uow = _unitOfWorkManager.Begin(requiresNew: true))?

@Stirda I have tried it but still not working, the sample of ABP on the first database only is working. What could be possible reasons for this to not work ?! Do you think this is a problem of dependency injection ? like it is injecting wrong context or anything else?

@Wello86

  1. Is this working out of tests?
  2. Did you write context.Services.AddAbpDbContext<MySecondDbContext>(options => options.AddDefaultRepositories(); }); in MyAppEntityFrameworkCoreModule.ConfigureServices?
  3. Did you apply https://github.com/abpframework/abp/issues/1153#issuecomment-496928705 ?

@Stirda Yes the application is working properly and I am using the default repositories every where. It is just the unit testing problem

@Stirda Could you please tell me your steps for two databases unit testing to compare with mine and try to discover what is missing. I made these
https://github.com/abpframework/abp/issues/1153#issuecomment-664030481

@Wello86 Sorry for late answer but I am quite busy. To answer you I would have to dig deeper in my old project. Maybe I will find time in next days but I am afraid not this week.

I see you asked Volosoft (https://github.com/abpframework/abp/issues/4955). I subscribed to your issue to be notified of the diagnosis.

Hi @Stirda, It seems that your solution worked it out in version 3.0.1 in insert seed data but in version 2.3.0 not needed however it fixed my problem in test method itself, however in other methods it worked without unitofworkmanager, so now it is working. Thnx a lot for you support.

Was this page helpful?
0 / 5 - 0 ratings