我有一种使用实体框架上下文获取雇主的方法(延迟加载已禁用)。有时我希望包括员工,有时我不希望在我的数据访问类中有以下代码:
public Employer GetEmployer(int employerId, bool includeRelationships)
{
Employer employer;
if (includeRelationships)
{
employer = (from e in this.context.Employers.Include(e => e.Employees)
where e.EmployerId == employerId
select e).SingleOrDefault();
}
else
{
employer = this.context.Employers.SingleOrDefault(e => e.EmployerId == employerId);
}
return employer;
}
从关于如何使用 NSubstitute 替换 EF 上下文返回的几个问题中,我在我的测试项目中有这个扩展方法来连接 DbSet 调用以进行替换(特别是NSubstitute DbSet / IQueryable<T>):
public static IDbSet<T> Initialise<T>(this IDbSet<T> dbSet, IQueryable<T> data) where T : class
{
dbSet.Provider.Returns(data.Provider);
dbSet.Expression.Returns(data.Expression);
dbSet.ElementType.Returns(data.ElementType);
dbSet.GetEnumerator().Returns(data.GetEnumerator());
return dbSet;
}
然后使用它来初始化测试类中的一组替代雇主:
[TestInitialize]
public void TestInitialise()
{
this.context = Substitute.For<EmployerContext>();
this.dao = new EmployerDao(this.context);
var employers = new List<Employer>();
var employerWithoutEmployee = new Employer { EmployerId = 1 };
employers.Add(employerWithoutEmployee);
var employerWithEmployee = new Employer { EmployerId = 2 };
var employee = new Employee { EmployeeId = 1, EmployerId = 2, Employer = employerWithEmployee };
employerWithEmployee.Employees.Add(employee);
employers.Add(employerWithEmployee);
this.substituteEmployers = Substitute.For<IDbSet<Employer>>().Initialise(employers.AsQueryable());
this.context.Employers.Returns(this.substituteEmployers);
}
所以,我现在有一个看起来像这样的测试:
[TestMethod]
public void ReturnsEmployerWithNullEmployeeWhenIncludeIsFalse()
{
// Assemble
var expectedEmployer = this.substituteEmployers.First(e => e.Employees.Any();
var employerId = expectedEmployer.EmployerId;
// Act
var actualEmployer = this.dao.GetEmployer(employerId, false);
var actualEmployee = actualEmployer.Employees.FirstOrDefault();
// Assert
Assert.AreSame(expectedEmployer, actualEmployer);
Assert.IsNotNull(actualEmployer);
Assert.IsNull(actualEmployee);
this.context.Employers.ReceivedWithAnyArgs();
}
此测试失败Assert.IsNull(actualEmployee);
在实际使用中,GetEmployer 将返回一个没有 Employee 孩子的 Employer。
但是,因为我用 Employee 替换了 Employer(因为这是我正在测试的!)该方法返回具有 Employee 的替换。
我该如何测试呢?
或者,我测试不正确?
我是否应该改用没有员工的雇主,因为这是上下文将返回的内容?
但这不是让测试毫无意义吗!?!
我在想自己在这里圈子......