Mock an Entity Framework class with JustMock inside another class

323 views Asked by At

I'm using JustMock and Entity Framework to try to write unit tests for a service. In the service, I have this method:

List<Log> GetLogType(string type)
{
    using (var db = new LogContext())
    {
        return db.Logs.Where(x => x.Type == type).ToList();
    }
}

And I have a test:

[TestMethod]
public void GetLogTypeTest()
{
    IList<Log> logs = new List<Log>
    {
        new Log() {
            Id = 1,
            Type = "Debug",
            Message = "Test Message"
        }
    };

    var logContext = Mock.Create<LogContext>(Constructor.Mocked).PrepareMock();
    logContext.Logs.Bind(logs);

    var service = new LogService();

    var debugs = service.GetLogType("Debug");

    Assert.AreEqual(1, debugs.Count());
}

How do I get the service to use my mocked context? Right now it is trying to connect to the database, and thus erroring.

1

There are 1 answers

2
kat1330 On BEST ANSWER

REASON

This is not happened because of JustMock. It happened because you creating new instance of LogContext in your method. Your method is not unit testable because it will always create new instance of service and establish connection with real database. There are several dependency injection frameworks suitable for C# please review Unity if you are interested.

TO FIX THIS

You have to use dependency injection and inject your service in class. In that case you can avoid connection to database. Your method will be like this:

List<Log> GetLogType(string type)
{
    return _logContext.Logs.Where(x => x.Type == type).ToList();    
}

_logContext is global variable of LogContext type which is injected trough constructor.

Than you can mock it and pass mock trough constructor.

Example of class can be:

public class LogService
{
    private readonly LogContext _logContext;

    public LogService(LogContext logContext)
    {
       _logContext = logContext;
    }

    List<Log> GetLogType(string type)
    {
        return _logContext.Logs.Where(x => x.Type == type).ToList();    
    }
}

Now you can create test case like in following:

[TestMethod]
public void GetLogTypeTest()
{
    IList<Log> logs = new List<Log>
    {
        new Log() {
            Id = 1,
            Type = "Debug",
            Message = "Test Message"
        }
    };

    var logContext = Mock.Create<LogContext>(Constructor.Mocked).PrepareMock();
    logContext.Logs.Bind(logs);

    var service = new LogService(logContext);

    var debugs = service.GetLogType("Debug");

    Assert.AreEqual(1, debugs.Count());
}

Please note what I did. I created service instance like you but I injected mocked instance of real service trough constructor. Mocked instance will never connect to database, it will return data which you provided in configuration.