【问题标题】:Unit Testing - updating model单元测试 - 更新模型
【发布时间】:2015-09-24 23:17:54
【问题描述】:

我是单元测试的新手,我正在尝试编写一个测试来验证当我更新我的用户对象时,正确的字段正在被更新。我的单元测试看起来像:

[Test]
public void ShouldUpdateExistingEmployee()
{
    var employees = new Employee[]
    {
        new Employee()
        {
            EmployeeId = 1,
            FirstName = "Johhn",
            LastName = "Smiths",
            Email = "John.Smith1@Illinois.gov",
            IsActive = true
         }
    };

    var mockContext = new Mock<SqlContext>();
    mockContext.Setup(e => e.Employees).ReturnsDbSet(employees);
    mockContext.Setup(m => m.Employees.Find(It.IsAny<object[]>()))
         .Returns<object[]>(
                  ids => employees.FirstOrDefault(d => d.EmployeeId == (int)ids[0]));

    var sut = new EmployeeRepository(mockContext.Object);

    var employeeToUpdate = new Employee
    {
        EmployeeId = 1,
        FirstName = "John",
        LastName = "Smith",
        Email = "John.Smith@Illinois.gov",
        IsActive = true
    };

    sut.Save(employeeToUpdate);

    Assert.That(employees.First().FirstName, Is.EqualTo(employeeToUpdate.FirstName));
    Assert.That(employees.First().LastName, Is.EqualTo(employeeToUpdate.LastName));
    Assert.That(employees.First().Email, Is.EqualTo(employeeToUpdate.Email));
}    

我的存储库如下所示:

public void Save(Employee employee)
{
    if (employee.EmployeeId > 0)
    {
        Employee dbEmployee = Context.Employees.Find(employee.EmployeeId);
        Context.Entry(dbEmployee).CurrentValues.SetValues(employee);
    }
    else
    {
        Context.Employees.Add(employee);
    }

    Context.SaveChanges();
}

问题是当我在我的存储库中访问 Context.Entry(dbEmployee).CurrentValues.SetValues(employee); 时,我收到以下错误:Member 'CurrentValues' cannot be called for the entity of type 'Employee' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet&lt;Employee&gt;.

任何帮助将不胜感激!

【问题讨论】:

    标签: c# entity-framework unit-testing nunit moq


    【解决方案1】:

    基于this article,你应该改变:

    Employee dbEmployee = Context.Employees.Find(employee.EmployeeId);
    Context.Entry(dbEmployee).CurrentValues.SetValues(employee);
    

    到:

    Context.Employees.Attach(employee)
    

    然后你应该改变你的断言来验证Attach方法是用employeeToUpdate调用的。(你在ReturnsDbSet方法中隐藏了DBSet&lt;&gt;所以我不能添加一个例子......)

    还有一件事,我认为您应该看看this code snippet,它显示了使用Moq 模拟DBContextDBSet&lt;&gt; 的正确方法。或read this article

    【讨论】:

    • 我会试一试。我从codethug.com/2015/03/20/mocking-dbset 中找到了ReturnsDbSet 扩展名,它和msdn 文章一样,除非你发现它有问题?
    • @Andrew 我在链接中看不到任何问题......使用CreateMockSet&lt;T&gt; 访问DBSet&lt;&gt;(使用Returns 而不是ReturnsDbSet)然后验证调用了 Attach 而不是多个断言
    • 所以因为我在调用Context.SaveChanges() 时调用了Attach,所以对象会被更新?我还需要Context.Employees.Find(employee.EmployeeId) 行吗?
    • @Andrew 根据文章你不再需要它了...(我在回答中写了)
    • 抱歉,最近一直很忙,没有机会尝试一下。这行不通。它附加实体,因此单元测试将通过,但是当我在我的服务(不是单元测试)中实际调用该方法时,它不会将更改保存到数据库中。我需要调用mockContextsetup 方法来附加实体吗?
    猜你喜欢
    • 2019-06-21
    • 2015-06-24
    • 2017-12-19
    • 2010-12-26
    • 2014-07-07
    • 2015-06-25
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多