C#/Moq-如何填写多级测试数据?
我是Moq新手,我想用它来编写单元测试。我有一个包含几个表的数据库,如:C#/Moq-如何填写多级测试数据?,c#,entity-framework,unit-testing,moq,C#,Entity Framework,Unit Testing,Moq,我是Moq新手,我想用它来编写单元测试。我有一个包含几个表的数据库,如: EducationUser | Application - UsrName - Student - UsrPwd - CourseId - UsrChallenge - Date - IsTeacher - Grade - FullName 这是一个位于localdb上的数据库,我想模拟它。我已经使用实体框架创建了实体。这些实体的接口是IEducationEntit
EducationUser | Application
- UsrName - Student
- UsrPwd - CourseId
- UsrChallenge - Date
- IsTeacher - Grade
- FullName
这是一个位于localdb
上的数据库,我想模拟它。我已经使用实体框架创建了实体。这些实体的接口是IEducationEntities
现在,我想创建一个模拟对象,并对一些Web服务进行一些测试,如:
[TestMethod()]
public void LoginTest()
{
HttpResponseMessage response = Request.CreateResponse(_accountController.Login("andrew", "DefaultPassword"));
Assert.IsTrue(response.IsSuccessStatusCode, "User unable to log in with correct login info");
}
为此,根据我从中了解到的情况,我应该能够做如下事情:
[TestClass()]
public class AccountControllerTests : ApiController
{
Mock<IEducationEntities> _entities = new Mock<IEducationEntities>(MockBehavior.Strict);
private AccountController _accountController;
public AccountControllerTests() {
_accountController = new AccountController(_entities.Object);
_entities.Setup(table => table.EducationUsers.UsrName).Returns("andrew");
_entities.Setup(table => table.EducationUsers.UsrPwd).Returns("DefaultPassword");
}
[TestMethod] //etc, defining tests below
[TestClass()]
公共类AccountControllerTests:ApiController
{
Mock _entities=新的Mock(MockBehavior.Strict);
私人账户控制人(AccountController);;
公共账户控制员测试(){
_accountController=新的accountController(_entities.Object);
_entities.Setup(table=>table.EducationUsers.UsrName).Returns(“andrew”);
_entities.Setup(table=>table.EducationUsers.UsrPwd).返回(“DefaultPassword”);
}
[TestMethod]//etc,在下面定义测试
但是,这根本不起作用,因为从数据库生成的实体显然不包含关于子字段的信息,我得到了错误:
“DbSet”不包含“UsrPwd”的定义,并且
没有接受类型为的第一个参数的扩展方法“UsrPwd”
可以找到“DbSet”(您是否缺少使用
指令或组件引用?)
我缺少什么?如何用与数据库结构相同的测试数据填充moq
对象?(假设您使用的是版本6或更高版本)
您将执行以下操作:
[TestMethod]
public void TestSomething()
{
// Create the user data
var educationUsers = new List<EducationUser>
{
new EducationUser
{
UsrName = "andrew",
UsrPwd = "DefaultPassword"
}
}.AsQueryable();
// Create the DbSet that contains the user data and wire it up to return the user data that was created above
Mock<DbSet<EducationUser>> educationUsersDbSet = new Mock<DbSet<EducationUser>>();
educationUsersDbSet.As<IQueryable<EducationUser>>().Setup(m => m.Provider).Returns(educationUsers.Provider);
educationUsersDbSet.As<IQueryable<EducationUser>>().Setup(m => m.Expression).Returns(educationUsers.Expression);
educationUsersDbSet.As<IQueryable<EducationUser>>().Setup(m => m.ElementType).Returns(educationUsers.ElementType);
educationUsersDbSet.As<IQueryable<EducationUser>>().Setup(m => m.GetEnumerator()).Returns(educationUsers.GetEnumerator());
// Create the mock context and wire up its EducationUsers property to return the DbSet that was created above
var context = new Mock<IEducationEntities>();
context.Setup(e => e.EducationUsers).Returns(educationUsersDbSet.Object);
// Create the account controller using the mock DbContext
_accountController = new AccountController(context.Object);
// ... the rest of your testing code ...
}
然后你的测试方法就变成了
[TestMethod]
public void TestSomething()
{
// Create the user data
var educationUsers = new List<EducationUser>
{
new EducationUser
{
UsrName = "andrew",
UsrPwd = "DefaultPassword"
}
}.AsQueryable();
// Create the DbSet that contains the user data and wire it up to return the user data that was created above
Mock<DbSet<EducationUser>> educationUsersDbSet = new CreateMockDbSet(educationUsers);
// Create the mock context and wire up its EducationUsers property to return the DbSet that was created above
var context = new Mock<IEducationEntities>();
context.Setup(e => e.EducationUsers).Returns(educationUsersDbSet.Object);
// Create the account controller using the mock DbContext
_accountController = new AccountController(context.Object);
// ... the rest of your testing code ...
}
[TestMethod]
公共空间
{
//创建用户数据
var educationUsers=新列表
{
新教育用户
{
UsrName=“安德鲁”,
UsrPwd=“DefaultPassword”
}
}.AsQueryable();
//创建包含用户数据的数据库集,并将其连接起来以返回上面创建的用户数据
Mock educationUsersDbSet=新建的CreateMockDbSet(educationUsers);
//创建模拟上下文并连接其EducationUsers属性以返回上面创建的DbSet
var context=newmock();
Setup(e=>e.EducationUsers).Returns(educationUsersDbSet.Object);
//使用模拟DbContext创建帐户控制器
_accountController=新的accountController(context.Object);
//…其余的测试代码。。。
}
在您的示例表结构中,password字段被称为UsrPassword
,但您在测试/模拟代码中称它为UsrPwd
。在我开始实现异步/等待模式之前,我也会采用上述方法。如果您阅读提供的链接,它会解释此方法不适用于此。此外,他们为async/await提供的方法不适用于EF Core,因此请注意。我现在使用EF Core的UseInMemoryDatabase对存储库层进行单元测试,取得了很大成功。如果您对示例感兴趣,我将提供一个示例。是的,我很想看一个示例。
[TestMethod]
public void TestSomething()
{
// Create the user data
var educationUsers = new List<EducationUser>
{
new EducationUser
{
UsrName = "andrew",
UsrPwd = "DefaultPassword"
}
}.AsQueryable();
// Create the DbSet that contains the user data and wire it up to return the user data that was created above
Mock<DbSet<EducationUser>> educationUsersDbSet = new CreateMockDbSet(educationUsers);
// Create the mock context and wire up its EducationUsers property to return the DbSet that was created above
var context = new Mock<IEducationEntities>();
context.Setup(e => e.EducationUsers).Returns(educationUsersDbSet.Object);
// Create the account controller using the mock DbContext
_accountController = new AccountController(context.Object);
// ... the rest of your testing code ...
}