Ecnerwal
Ecnerwal

Reputation: 372

Unit Testing with Microsoft EntityFramework

I have a currently small personnal project that I want to start off on the right foot which means making sure that my fonctions are unit tested. My application normally use the data context S_ERP_DBEntities but when testing I'd want to change the data context to Test_S_ERP_DBEntities. This is what I have so far but i am really not sure. The view by default calls the default constructor which means that I'd have the right data context when not testing since the default constructor doesn't change it.

LoginViewModel.cs

private object dbContext = new S_ERP_DBEntities();

    public LoginViewModel(object dbEntities)
    {
        dbContext = dbEntities;
    }

Unittest1.cs

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var dbContext = new Test_S_ERP_DBEntities();
        var login = new LoginViewModel(dbContext);
    }
}

That would work but I don't know if there is a more elegant way of doing it. Any feedback will be appreciated.

Thanks

Upvotes: 4

Views: 96

Answers (1)

Arian Motamedi
Arian Motamedi

Reputation: 7423

What you are doing is actually a very common way of testing a layer, it's called Dependency Injection. To make it slightly more elegant, you can have a default constructor that initializes dbContext to whatever it needs to be at runtime:

private object dbContext;

public LoginViewModel()
{
    dbContext = new S_ERP_DBEntities();
}

public LoginViewModel(object dbEntities)
{
    dbContext = dbEntities;
}

This way the "real" object creating an instance of this View Model won't have to worry about initializing dbContext and can simply use the default constructor, while your unit tests can call the overload to "inject the dependency".

As a side note, I'd change the type on dbContext to its actual type instead of object. I'm assuming you are using object because you have two different context types: S_ERP_DBEntities and Test_S_ERP_DBEntities. This, while works, is a code smell, since unit tests normally don't rely on the database. Instead of creating a different context that talks to your database for testing, you should instead create a mocked (read: fake) instance of S_ERP_DBEntities and pass that in when testing your view model. The key thing to note here is this: it is safe to assume Microsoft has already unit-tested Entity Framework, so you can safely mock it. See this link on using Mock with Entity Framework for more information.

Upvotes: 3

Related Questions