If you are using entity framework you can't unit test your data access layer.
Solution provided by Erik Alsmyr is very wrong!
Look here why - What's the point of in memory IDbSet?.
When you use in memory db sets you are running Linq to Objects. When you use EF's DbContext your Linq is converted to SQL. Those are two different things!
It is very easy to write code that will work with in memory db set (all your unit tests will pass and you will be happy) just to notice runtime error first time you try to hit database.
Let's modify this code a bit. I don't think FULLNAME should have setter if we are using FIRSTNAME, LASTNAME. It should be calculated from FIRSTNAME and LASTNAME.
class User
{
public string FIRSTNAME { get; set; }
public string LASTNAME { get; set; }
public string FULLNAME
{
get { return string.Format("{0}, {1}", LASTNAME, FIRSTNAME }
}
User(string firstName, string lastName)
{
this.FIRSTNAME = firstName;
this.LASTNAME = lastName;
}
}
Now you can write test like this and it will pass (of course after you implement it in controller)
public IMyEntities GetRepoWithUsers(params User[] users)
{
var inMemoryUsers = new InMemoryDbSet<User>();
var mockData = new Mock<IMyEntities>();
mockData.Setup(m => m.Users).Returns(inMemoryUsers);
return mockData.Object;
}
[Test]
public void GetUserByFullname()
{
var ankaArne = new User("Arne", "Anka");
var bjornBertil = new User("Bertil", "Björn");
var repo = GetRepoWithUsers(ankaArne, bjornBertil);
var usersController = new UsersController(repo);
var found = usersController.GetUser("Anka, Arne");
Assert.NotNull(found);
Assert.AreEqual("Anka", found.LASTNAME);
Assert.AreEqual("Arne", found.FIRSTNAME);
}
But when you run it against 'real' DbContext and 'real' DbSet it will throw because you can't do Linq queries on calculated properties. Only on those that are mapped to database columns. So what's the point of that test?