【发布时间】:2015-03-03 22:48:24
【问题描述】:
我正在尝试找出最好的方法 - 我已经搜索了几个小时,但无法让它发挥作用。我需要一双全新的眼睛和视角。
我正在尝试创建一个简单的应用程序。 它将使用 EF 6.1.0 作为 DAL。
我有一个名为 User 的实体。 我有另一个名为 WorkItem 的实体
一个用户可以拥有多个 WorkItem。
我创建了一个名为“TimesheetsContext”的 EFDbContext。它继承自 DbContext 并具有 2 个虚拟属性:
public virtual IDbSet<WorkItem> WorkItems { get; set; }
public virtual IDbSet<User> Users { get; set; }
我还有一个 IUnitOfWork(及其具体类)
public interface IUnitOfWork
{
ITimeSheetContext Context { get; set; }
IWorkItemRepository WorkItemRepository { get; set; }
IUserRepository UserRepository { get; set; }
}
WorkItem 和 User 存储库仅具有 Add、Login、Update 等功能,这些功能又调用 EfDBContext 来执行请求操作。
现在,我想创建一个单元测试,以便能够模拟 DbContext 并能够添加用户或工作项。但是,我似乎无法让它工作。
一旦在您的帮助下,我已经做到了这一点,我可以轻松地将其更改为使用服务层并传入 IUnitOfWork。
使用 Moq 和 EntityFramework.Testing.Moq,我无法让它工作:
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);
最后,我进行了这样的测试,但是当我添加用户时,我仍然返回 3 并且断言失败:
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());
我是不是走错了路?
【问题讨论】:
-
究竟会发生什么?
-
@JohnSaunders - 当我添加一个新的用户项目时,上下文仍然包含 3 个项目,而不是 4 个。我希望能够在调用模拟的上下文/存储库时坚持并查看任何更新/更改
-
这可能会让你很感兴趣:vannevel.net/blog/2015/02/26/11
标签: c# entity-framework unit-testing moq