1

I'm trying to add some integration tests for my database access logic using EF code-first 6.1.2. I'd like to do this on a separate database so that I don't mess up m production database with test data.

Also, the test should be repeatable which means the database should be created if not exists, seed test data, run the tests and finally delete it when done.

I don't see how this can be done without Enable-Migrations command for the test database too.

This would be my dbContext for production:

public partial class ApplicationDbContext : 
        IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IApplicationDbContext
{
    public ApplicationDbContext() : base("name=DefaultConnection") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        if (base.Database.Connection.ConnectionString == "DefaultConnectionTest")
            Database.SetInitializer(new DropCreateDatabaseAlways<ApplicationDbContext>());
        else
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());

        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUser>().ToTable("Users");
        modelBuilder.Entity<ApplicationRole>().ToTable("Roles");
        modelBuilder.Entity<ApplicationUserRole>().ToTable("UserRoles");
        modelBuilder.Entity<ApplicationUserLogin>().ToTable("UserLogins");
        modelBuilder.Entity<ApplicationUserClaim>().ToTable("UserClaims");
    }

    public DbSet<Order> Orders { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Person> Persons { get; set; }
}

I have everything set up using Dependency Injection from Ninject. Adding an extra constructor with the connection string as parameter public ApplicationDbContext(string dbConnection) : base(dbConnection) { }, would still leave me to run the Enable-Migrations command.

Is there some way to automate this process? Or can anyone suggest something else?

I'd like to stick with SQL Server database as working with a different database for testing might give me false positives.

1 Answer 1

6

You have to use a database initialiser. There are a few available :

Database.SetInitializer(new CreateDatabaseIfNotExists<InterstoneContext>());
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<InterstoneContext>());
Database.SetInitializer(new DropCreateDatabaseAlways<InterstoneContext>());

you need the third option. Be careful with your connectionstring that you don't overwrite your production database.

Sign up to request clarification or add additional context in comments.

11 Comments

I know which initializer I need to use, but how does that Enable-Migrations for the test database? The initializer you see in my question is for the production database.
I don't understand your remark, i thought you did not want migration. The third option would always create a new database, in which you can seed test data if you want.
It's not what I want, I was under the impression that for code first you have to enable migrations. Are you saying that's unnecessary? And how would I pass the connection string to use for the 3rd option?
no you don't have to enable migration. How you pass the connection string depends on your implementation. In your case you would need to add a string to the ApplicationDbContext class, so you can pass a different string for your tests than the one you use for production. I am using unity, so I rely more on dependency injection even for the connection string.
I have DI setup too but I'm using Ninject. And I have added an extra constructor that takes a connection string, see my code in my question. Also, I just tried your approach, the test database didn't got created when I ran the test. Here the result: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Cannot open database "DefaultConnectionTest" requested by the login. Hope you can walk me through the steps making this work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.