使用 Moq 对 dbContext 的添加操作进行单元测试
Unit testing add operation of a dbContext using Moq
我正在尝试在我的应用程序开发中启动 TDD,我正在使用 xunit 和 moq 模拟单元测试 entityframework 操作,我在测试更新或删除操作时没有任何问题,但不幸的是,由于没有这方面的经验,我在检查特定实体的添加方法时遇到了问题。
每当我想在执行 SaveChanges() 后测试 add 方法时,我的上下文(模拟实体列表)被设置为 null,因此我无法再在我的业务代码中使用此上下文。
我用作参考的 link 如下:
https://msdn.microsoft.com/en-us/data/dn314429.aspx#virtual
这是我的业务代码:
public class PersonBL
{
/// <summary>
/// DataContext item of this business.
/// </summary>
private UnitTestSampleEntities DataContext;
/// <summary>
/// Initializes a new instance of the <see cref="PersonBL"/> current business class for Person.
/// </summary>
/// <param name="dataContext">The data context.</param>
public PersonBL()
{
this.DataContext = new UnitTestSampleEntities();
}
public PersonBL(UnitTestSampleEntities dbContext)
{
this.DataContext = dbContext;
}
/// <summary>
/// Adds the new person.
/// </summary>
/// <param name="person">The person.</param>
public void AddPerson(Person person)
{
this.DataContext.People.Add(person);
this.DataContext.SaveChanges();
}
public void UpdatePerson(Person person)
{
var p = this.DataContext.People.Where(i => i.ID == person.ID).FirstOrDefault<Person>();
if (p != null)
{
p.FirstName = person.FirstName;
p.LastName = person.LastName;
p.PhoneNo = person.PhoneNo;
}
this.DataContext.SaveChanges();
}
public void DeletePerson(Person person)
{
var p = this.DataContext.People.Where(i => i.ID == person.ID).FirstOrDefault<Person>();
if (p != null)
{
this.DataContext.People.Remove(p);
}
this.DataContext.SaveChanges();
}
public List<Person> GetPeopleListByDeptID(int deptID)
{
return (from person in this.DataContext.People
select person)
.Where(i => i.DeptId == deptID)
.ToList();
}
}
这是我的测试方法:
[Fact]
public void TestAddPerson2()
{
//Prepare the data
var data = new List<Person>
{
new Person { ID=1,
FirstName="Joey",
LastName="Clark",
PhoneNo="02188882525",
DeptId=1},
new Person {ID=2,
FirstName="John",
LastName="Peterson",
PhoneNo="02188884747",
DeptId=1},
new Person {ID=3,
FirstName="Ross",
LastName="Geller",
PhoneNo="02188883366",
DeptId=1},
}.AsQueryable();
var mockSet = new Mock<DbSet<Person>>();
mockSet.As<IQueryable<Person>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Person>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Person>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Person>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<UnitTestSampleEntities>();
int addCount = 0;
//setup the mock context
// mockContext.Setup(m => m.People).Returns(mockSet.Object);
mockContext.Setup(m => m.People).Callback(() => addCount++);
// mockContext.Setup(m => m.Add(It.IsAny<Person>())).Callback(() => addCount++);
var personBL = new PersonBL(mockContext.Object);
var person = new Person()
{
FirstName = "John",
LastName = "Clark",
PhoneNo = "02188887788"
};
personBL.AddPerson(person);
Assert.Equal(4, data.Count());
mockSet.Verify(m => m.Add(It.IsAny<Person>()), Times.Once());
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}
我正在寻找一种方法来在保存新记录后检查记录数,或检查实体的 属性 的值,以及在添加操作后使用 DataContext 的方法(为什么它是空的?)
使用存储库模式。并为您的单元测试准备一个 MockRepository。
在这里查看我的回答:
我正在尝试在我的应用程序开发中启动 TDD,我正在使用 xunit 和 moq 模拟单元测试 entityframework 操作,我在测试更新或删除操作时没有任何问题,但不幸的是,由于没有这方面的经验,我在检查特定实体的添加方法时遇到了问题。 每当我想在执行 SaveChanges() 后测试 add 方法时,我的上下文(模拟实体列表)被设置为 null,因此我无法再在我的业务代码中使用此上下文。 我用作参考的 link 如下:
https://msdn.microsoft.com/en-us/data/dn314429.aspx#virtual
这是我的业务代码:
public class PersonBL
{
/// <summary>
/// DataContext item of this business.
/// </summary>
private UnitTestSampleEntities DataContext;
/// <summary>
/// Initializes a new instance of the <see cref="PersonBL"/> current business class for Person.
/// </summary>
/// <param name="dataContext">The data context.</param>
public PersonBL()
{
this.DataContext = new UnitTestSampleEntities();
}
public PersonBL(UnitTestSampleEntities dbContext)
{
this.DataContext = dbContext;
}
/// <summary>
/// Adds the new person.
/// </summary>
/// <param name="person">The person.</param>
public void AddPerson(Person person)
{
this.DataContext.People.Add(person);
this.DataContext.SaveChanges();
}
public void UpdatePerson(Person person)
{
var p = this.DataContext.People.Where(i => i.ID == person.ID).FirstOrDefault<Person>();
if (p != null)
{
p.FirstName = person.FirstName;
p.LastName = person.LastName;
p.PhoneNo = person.PhoneNo;
}
this.DataContext.SaveChanges();
}
public void DeletePerson(Person person)
{
var p = this.DataContext.People.Where(i => i.ID == person.ID).FirstOrDefault<Person>();
if (p != null)
{
this.DataContext.People.Remove(p);
}
this.DataContext.SaveChanges();
}
public List<Person> GetPeopleListByDeptID(int deptID)
{
return (from person in this.DataContext.People
select person)
.Where(i => i.DeptId == deptID)
.ToList();
}
}
这是我的测试方法:
[Fact]
public void TestAddPerson2()
{
//Prepare the data
var data = new List<Person>
{
new Person { ID=1,
FirstName="Joey",
LastName="Clark",
PhoneNo="02188882525",
DeptId=1},
new Person {ID=2,
FirstName="John",
LastName="Peterson",
PhoneNo="02188884747",
DeptId=1},
new Person {ID=3,
FirstName="Ross",
LastName="Geller",
PhoneNo="02188883366",
DeptId=1},
}.AsQueryable();
var mockSet = new Mock<DbSet<Person>>();
mockSet.As<IQueryable<Person>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Person>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Person>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Person>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<UnitTestSampleEntities>();
int addCount = 0;
//setup the mock context
// mockContext.Setup(m => m.People).Returns(mockSet.Object);
mockContext.Setup(m => m.People).Callback(() => addCount++);
// mockContext.Setup(m => m.Add(It.IsAny<Person>())).Callback(() => addCount++);
var personBL = new PersonBL(mockContext.Object);
var person = new Person()
{
FirstName = "John",
LastName = "Clark",
PhoneNo = "02188887788"
};
personBL.AddPerson(person);
Assert.Equal(4, data.Count());
mockSet.Verify(m => m.Add(It.IsAny<Person>()), Times.Once());
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}
我正在寻找一种方法来在保存新记录后检查记录数,或检查实体的 属性 的值,以及在添加操作后使用 DataContext 的方法(为什么它是空的?)
使用存储库模式。并为您的单元测试准备一个 MockRepository。
在这里查看我的回答: