I am trying to find out the best way to do this - I have searched ALOT for a few hours but cannot get this to work. I need a fresh pair of eyes and perspective.
I am trying to create a straight forward app. It will be using EF 6.1.0 as the DAL.
I have an entity called User. I have another entity called WorkItem
a user can have many WorkItems.
I have created a EFDbContext called "TimesheetsContext". It inherits from DbContext and has 2 virtual properties:
public virtual IDbSet<WorkItem> WorkItems { get; set; }
public virtual IDbSet<User> Users { get; set; }
I also have an IUnitOfWork (and its concrete class)
public interface IUnitOfWork
{
ITimeSheetContext Context { get; set; }
IWorkItemRepository WorkItemRepository { get; set; }
IUserRepository UserRepository { get; set; }
}
The WorkItem and User repository simply has functions such as Add, Login, Update, which in turn calls the EfDBContext to perform the request operation.
Now, I want to create a unit test to be able to mock up the DbContext and be able to add users or work items. However, I cannot seem to get it to work.
Once, with your help, I have got this far, I can then easily change it to use a services layer and pass in an IUnitOfWork.
Using Moq and EntityFramework.Testing.Moq, I cannot get it to work:
private Mock<TimeSheetContext> _mockContext;
// <snip />
Guid userId1 = Guid.NewGuid();
Guid userId2 = Guid.NewGuid();
Guid userId3 = Guid.NewGuid();
var users = new List<User>(new[]
{
new User { Firstname = "Joe", Lastname = "Bloggs", Password = "pass1", UserId = userId1, Username = "JoeBloggs" },
new User { Firstname = "Thom", Lastname = "Stevens", Password = "pass2", UserId = userId2, Username = "ThomStevens"},
new User { Firstname = "Homer", Lastname = "Simpson", Password = "pass3", UserId = userId3, Username = "HomerSimpson" }
}).AsQueryable();
var tasks = new List<LionTask>(new[]
{
new WorkItem { CreatedDate = DateTime.Today, Description = "Desc1", ModifiedDate = DateTime.Today, State = 1, TaskId = Guid.NewGuid(), Title = "Test Title", UserId = userId1 },
new WorkItem { CreatedDate = DateTime.Today, Description = "Desc2", ModifiedDate = DateTime.Today, State = 2, TaskId = Guid.NewGuid(), Title = "Test Title 2", UserId = userId2 },
new WorkItem { CreatedDate = DateTime.Today, Description = "Desc3", ModifiedDate = DateTime.Today, State = 3, TaskId = Guid.NewGuid(), Title = "Test Title 3", UserId = userId3 }
}).AsQueryable();
this._mockContext = new Mock<TimeSheetContext>();
var taskDbSetMock = new Mock<IDbSet<WorkItem>>();
var userDbSetMock = new Mock<IDbSet<User>>();
userDbSetMock.As<IQueryable<User>>().Setup(m => m.Provider).Returns(users.Provider);
userDbSetMock.As<IQueryable<User>>().Setup(m => m.Expression).Returns(users.Expression);
userDbSetMock.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(users.ElementType);
userDbSetMock.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(users.GetEnumerator());
taskDbSetMock.As<IQueryable<WorkItem>>().Setup(m => m.Provider).Returns(tasks.Provider);
taskDbSetMock.As<IQueryable<WorkItem>>().Setup(m => m.Expression).Returns(tasks.Expression);
taskDbSetMock.As<IQueryable<WorkItem>>().Setup(m => m.ElementType).Returns(tasks.ElementType);
taskDbSetMock.As<IQueryable<WorkItem>>().Setup(m => m.GetEnumerator()).Returns(tasks.GetEnumerator());
this._mockContext.Setup(c => c.Users).Returns(userDbSetMock.Object);
this._mockContext.Setup(c => c.WorkItems).Returns(taskDbSetMock.Object);
Finally, I then have a test like this but when I add a user, I still get back 3 and the Assert fails:
User u = new User { Firstname = "Timmy", Lastname = "Johanson", Password = "omg123", UserId = Guid.NewGuid(), Username = "TJ" };
this._mockContext.Object.Users.Add(u);
Assert.AreEqual(4, this._mockContext.Object.Users.Count());
am I going about this the wrong way?