Base solution for your next web application
Open Closed

Unit Testing w/Live DB #3616


User avatar
0
bbakermmc created

Is there a way to setup a unit test/appservice/change out the context to use a read DB instead of in memory?


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

    Hi @BBakerMMC,

    Do you use ASP.NET Core version or ASP.NET MVC 5.x ?

    Thanks.

  • User Avatar
    0
    bbakermmc created

    ASP.NET Core

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Haven't tried it but replacing ServiceCollectionRegistrar in unit test project with the one in Migrator project should do this. You should also add a appsettings.json and connection string in it for unit tests project.

    But testing with real db is a bit hard. You need to recreate the db before running each unit test.

    Thanks.

  • User Avatar
    0
    bbakermmc created

    Shouldn't there be an easier way to test our app services using real data? No one in their right mind is going to mock up data for every table they have.

    Ideally I just want to say use this app service using this db context/connection string.

    I'm not looking to run the test cases for all the stuff you guys wrote, its more for my own stuff.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    AspNet Zero does not provide such a solution for unit tests. But, you can create a similar unit test project in your solution and you can place your own unit tests in it and use a real database for your unit tests.

    Thanks.

  • User Avatar
    0
    bbakermmc created

    Can you guys provide a GIST/small project that implements this. I need to be able to login as a tenant and run an app service.

    I tried copying your test project and swapping out the ServiceCollectionRegistrar but it throws an error.

    This gets me half way there:

    public static void Register(IIocManager iocManager)
            {
                RegisterIdentity(iocManager);
    
                var builder = new DbContextOptionsBuilder<PlatformDbContext>();
                builder.UseSqlServer("Server=mmcsqldev02; Database=MMCPlatformControl_BradV2; Trusted_Connection=True;", o => o.UseRowNumberForPaging());
    
                         iocManager.IocContainer.Register(
                    Component
                        .For<DbContextOptions<PlatformDbContext>>()
                        .Instance(builder.Options)
                        .LifestyleSingleton()
                );
            }
    

    How do I make this change the connection to the clients db now, I'm missing something to change the ctx?

    protected void LoginAsTenant(string tenancyName, string userName)
            {
                AbpSession.TenantId = null;
    
                var tenant = UsingDbContext(context => context.Tenants.FirstOrDefault(t => t.TenancyName == tenancyName));
                if (tenant == null)
                {
                    throw new Exception("There is no tenant: " + tenancyName);
                }
    
                AbpSession.TenantId = tenant.Id;
                if (string.IsNullOrEmpty(tenant.ConnectionString))
                {
                    var user = UsingDbContext(
                        context => context.Users.FirstOrDefault(
                            u => u.TenantId == AbpSession.TenantId && u.UserName == userName));
                    if (user == null)
                    {
                        throw new Exception("There is no user: " + userName + " for tenant: " + tenancyName);
                    }
    
                    AbpSession.UserId = user.Id;
                }
                else
                {
                    var connString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString);
    
                    var builder = new DbContextOptionsBuilder<PlatformDbContext>();
                    builder.UseSqlServer(connString, o => o.UseRowNumberForPaging());
                    
                    var ctx = new PlatformDbContext(builder.Options);
                    
                    var user = UsingDbContext(
                        context => context.Users.FirstOrDefault(
                            u => u.TenantId == AbpSession.TenantId && u.UserName == userName));
                    if (user == null)
                    {
                        throw new Exception("There is no user: " + userName + " for tenant: " + tenancyName);
                    }
    
                    AbpSession.UserId = user.Id;
    
                }
                
            }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @BBakerMMC,

    We will prepare a sample or maybe a article about this but it might take a few days to prepare. I will let you know when it's done.

    Thanks.

  • User Avatar
    0
    bbakermmc created

    Bump

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @BBakerMMC,

    Sorry for the delay. We couldn't hav etime for this yet. We will let you know when it is done.

    Thanks.

  • User Avatar
    0
    bbakermmc created

    Bump. Also added Issue for this.

  • User Avatar
    0
    exlnt created

    Bump.

    Has anyone been able to get this to work? I really would prefer to test against a live DB. The in-memory DB testing is not realistic. As my application is advancing and more tables are introduced, I would have to create so many data entries into the "Databuilder" class. Plus worry about all the FK relationships. It's just not practical.

  • User Avatar
    1
    aaron created
    Support Team

    Yes, see #4659 (answer).

    GitHub issue mentioned above: aspnetzero/aspnet-zero-core#764