如何在 ASP.NET WebApi 中模拟 class?
How to mock class in ASP.NET WebApi?
我需要模拟简单的 class :
namespace Infrastructure.Repositores
{
public class StudentRepository : IStudentRepository
{
private readonly GradeBookDBContext _dbContext;
public StudentRepository(GradeBookDBContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<Student> GetAllStudents()
{
var students = _dbContext.Students;
return students;
}
我尝试做这样的事情,但它不起作用...我是模拟测试的初学者,有人可以解释为什么它不起作用吗?
[Fact]
public void Test2()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(SampleStudents);
StudentRepository ss = new StudentRepository();
var expected = SampleStudents();
var actual = ss.GetAllStudents();
Assert.Equal(expected, actual);
}
private List<Student> SampleStudents()
{// list of sample objects}
如何模拟此 class 保持良好做法?
.Returns(SampleStudents)
必须是 .Returns(SampleStudents())
,尽管 Assert.Equal(预期的,实际的)仍然会抛出异常,除非 Student
是 struct
然后就是这一行StudentRepository ss = new StudentRepository();
。创建模拟然后使用原始 class
没有意义
所以你应该这样做
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = Sample();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var actual = studentRepositoryMock.Object.GetAllStudents();
Assert.Equal(expected, actual);
}
显然这没有意义,因为您不会以这种方式测试任何有用的东西。如果您想测试 StudentRepository,只需创建 StudentRepository 并对其进行测试。当你有一个使用它的 class 时,为 IStudentRepository 创建模拟是有意义的,例如
public class StudentService
{
private IStudentRepository _repo;
public StudentService(IStudentRepository repo)
{
_repo = repo;
}
public List<Student> GetIgors()
{
return _repo.GetAllStudents().Where(x => x.Name == "Igor").ToList();
}
}
那么你的测试应该是这样的
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = new List<Student>()
{
new Student() {Name = "Igor"},
new Student() {Name = "NotIgor"}
};
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var sm = new StudentService(studentRepositoryMock.Object);
var actual = sm.GetIgors();
Assert.True(actual.All(x => x.Name == "Igor"));
}
免责声明:我实际上并不建议您以这种方式编写数据库查询,在将集合转换为 IEnumerable
之前过滤元素,这只是使用 moq 库的示例。如果您想测试存储库检查 this article ,请不要为此使用最小起订量库。
我需要模拟简单的 class :
namespace Infrastructure.Repositores
{
public class StudentRepository : IStudentRepository
{
private readonly GradeBookDBContext _dbContext;
public StudentRepository(GradeBookDBContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<Student> GetAllStudents()
{
var students = _dbContext.Students;
return students;
}
我尝试做这样的事情,但它不起作用...我是模拟测试的初学者,有人可以解释为什么它不起作用吗?
[Fact]
public void Test2()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(SampleStudents);
StudentRepository ss = new StudentRepository();
var expected = SampleStudents();
var actual = ss.GetAllStudents();
Assert.Equal(expected, actual);
}
private List<Student> SampleStudents()
{// list of sample objects}
如何模拟此 class 保持良好做法?
.Returns(SampleStudents)
必须是 .Returns(SampleStudents())
,尽管 Assert.Equal(预期的,实际的)仍然会抛出异常,除非 Student
是 struct
然后就是这一行StudentRepository ss = new StudentRepository();
。创建模拟然后使用原始 class
所以你应该这样做
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = Sample();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var actual = studentRepositoryMock.Object.GetAllStudents();
Assert.Equal(expected, actual);
}
显然这没有意义,因为您不会以这种方式测试任何有用的东西。如果您想测试 StudentRepository,只需创建 StudentRepository 并对其进行测试。当你有一个使用它的 class 时,为 IStudentRepository 创建模拟是有意义的,例如
public class StudentService
{
private IStudentRepository _repo;
public StudentService(IStudentRepository repo)
{
_repo = repo;
}
public List<Student> GetIgors()
{
return _repo.GetAllStudents().Where(x => x.Name == "Igor").ToList();
}
}
那么你的测试应该是这样的
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = new List<Student>()
{
new Student() {Name = "Igor"},
new Student() {Name = "NotIgor"}
};
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var sm = new StudentService(studentRepositoryMock.Object);
var actual = sm.GetIgors();
Assert.True(actual.All(x => x.Name == "Igor"));
}
免责声明:我实际上并不建议您以这种方式编写数据库查询,在将集合转换为 IEnumerable
之前过滤元素,这只是使用 moq 库的示例。如果您想测试存储库检查 this article ,请不要为此使用最小起订量库。