Stefan Schmid
Stefan Schmid

Reputation: 1042

Mock DbContext with FakeDbSets

I want to create a mocked DbContext using faked DbSets. So I've created a class called FakeDbSet<T> which implements IDbSet<T>.

Now I've created a FakeDbContext which has those faked DbSet<T>s in it. I've bound DbContext to FakeDbContext with Ninject like this:

Kernel.Bind<DbContext>().To<FakeDbContext>();

When I call my WebAPI project I'll get an SqlException that I don't have the permission to create the database.

This is my FakeDbContext:

public class FakeDbContext : DbContext
{
    public virtual IDbSet<User> Users => new UserDbSet();
}

(Note: UserDbSet just fills the HashSet<User> with default data.)

How do I set my FakeDbContext to not create/interact with a real database? If I remove the : DbContext from the FakeDbContext Ninject says that it must be convertible to DbContext.

Upvotes: 0

Views: 661

Answers (2)

Stefan Schmid
Stefan Schmid

Reputation: 1042

I've finally fixed ith with qujck's help.

The reason why I was getting an exception because my DbContext tried to connect to the database was, that I was using DbContext.Set<T> which was accessing the database.

Overriding the Set<T> method fixed the problem.

Upvotes: 0

qujck
qujck

Reputation: 14578

Try disabling database initialisation

public class FakeDbContext : DbContext
{
    static FakeDbContext()
    {
        Database.SetInitializer<FakeDbContext>(null);
    }

    public FakeDbContext() { }

    public virtual IDbSet<User> Users => new UserDbSet();
}

This test works for me:

[Fact]
public void Test1()
{
    var kernel = new StandardKernel();
    kernel.Bind<RealContext>().To<FakeDbContext>();

    var result = kernel.Get<Wrapper>();

    var user = result.context.Users.Add(new User());
    Assert.NotNull(user);
}

public class Wrapper
{
    public readonly RealContext context;

    public Wrapper(RealContext context)
    {
        this.context = context;
    }
}

public class RealContext : DbContext
{
    public virtual IDbSet<User> Users => new UserDbSet();
}

public class FakeDbContext : RealContext
{
    static FakeDbContext()
    {
        Database.SetInitializer<FakeDbContext>(null);
    }

    public override IDbSet<User> Users => new UserDbSet();
}

// .....

Upvotes: 2

Related Questions