C# MVC、通用存储库和 Moq 单元测试
C# MVC, Generic Repository and Unit Testing with Moq
我必须测试一种方法,如果日期范围与列表中的任何项目重叠,return判断真假。
列表项是假期请求:
public class HolidayRequest
{
public int Id { get; set; }
public string EmployeeId { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
}
public interface IHolidayRequestRepository :IGenericRepository<HolidayRequest>
{
bool IsHolidayRequestAlreadyCreated(String EmployeeId, DateTime DateFrom, DateTime DateTo);
}
public interface IGenericRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> GetAll();
TEntity Get(object id);
//skipped
}
现在进行单元测试:
[TestClass]
public class UnitTest1
{
private Mock<IHolidayRequestRepository > _holidayRepository;
[TestInitialize]
public void Initialize()
{
_holidayRepository = new Mock<IHolidayRequestRepository >();
}
[TestMethod]
public void TestMethod1()
{
//Arange
IList<HolidayRequest> list = new List<HolidayRequest>
{
new HolidayRequest{ Id =1, EmployeeId="E00001", DateFrom = new DateTime(2019,09,13,0,0,0), DateTo = new DateTime(2019,09,13,0,0,0)}
};
_holidayRepository.Setup(x => x.GetAll()).Returns(list.AsQueryable);
var howMany = _holidayRepository.Object.GetAll().Count();
//Assert
Assert.AreEqual(1, howMany); //<- Test passed
bool val = _holidayRepository.Object
.IsHolidayRequestAlreadyCreated("E00001", new DateTime(2019, 9, 12), new DateTime(2019, 9, 14));
////Assert
Assert.IsTrue(val); //<- Test error - always return false
}
}
我希望测试结果为真,但它总是return假,即使方法被简化为return总是真
方法:
bool IsHolidayRequestAlreadyCreated(String EmployeeId, DateTime DateFrom, DateTime DateTo);
已简化为始终 return true:
public class HolidayRequestRepository : GenericRepository<HolidayRequest>, IHolidayRequestRepository
{
public HolidayRequestRepository(MvcDbContext context) : base(context) { }
public bool IsHolidayRequestAlreadyCreated(string EmployeeId, DateTime DateFrom, DateTime DateTo)
{
return true;
}
}
我应该如何模拟此方法以使用来自 HolidayRequestRepository class 的逻辑?
问题是您没有测试代码的真实实现,而是测试了模拟代码。在单元测试中,您通常希望测试真正的实现。因此,在您的情况下,您必须创建 HolidayRequestRepository
的实例并在此对象上调用该方法,例如
var hrr = new HolidayRequestRepository(...);
var actual = hrr.IsHolidayRequestAlreadyCreated(empId, dtFrom, dtTo);
Assert.True(actual);
为了使其工作,您需要设置提供给构造函数的 DbContext,以便测试用例所需的数据可用。
我必须测试一种方法,如果日期范围与列表中的任何项目重叠,return判断真假。
列表项是假期请求:
public class HolidayRequest
{
public int Id { get; set; }
public string EmployeeId { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
}
public interface IHolidayRequestRepository :IGenericRepository<HolidayRequest>
{
bool IsHolidayRequestAlreadyCreated(String EmployeeId, DateTime DateFrom, DateTime DateTo);
}
public interface IGenericRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> GetAll();
TEntity Get(object id);
//skipped
}
现在进行单元测试:
[TestClass]
public class UnitTest1
{
private Mock<IHolidayRequestRepository > _holidayRepository;
[TestInitialize]
public void Initialize()
{
_holidayRepository = new Mock<IHolidayRequestRepository >();
}
[TestMethod]
public void TestMethod1()
{
//Arange
IList<HolidayRequest> list = new List<HolidayRequest>
{
new HolidayRequest{ Id =1, EmployeeId="E00001", DateFrom = new DateTime(2019,09,13,0,0,0), DateTo = new DateTime(2019,09,13,0,0,0)}
};
_holidayRepository.Setup(x => x.GetAll()).Returns(list.AsQueryable);
var howMany = _holidayRepository.Object.GetAll().Count();
//Assert
Assert.AreEqual(1, howMany); //<- Test passed
bool val = _holidayRepository.Object
.IsHolidayRequestAlreadyCreated("E00001", new DateTime(2019, 9, 12), new DateTime(2019, 9, 14));
////Assert
Assert.IsTrue(val); //<- Test error - always return false
}
}
我希望测试结果为真,但它总是return假,即使方法被简化为return总是真
方法:
bool IsHolidayRequestAlreadyCreated(String EmployeeId, DateTime DateFrom, DateTime DateTo);
已简化为始终 return true:
public class HolidayRequestRepository : GenericRepository<HolidayRequest>, IHolidayRequestRepository
{
public HolidayRequestRepository(MvcDbContext context) : base(context) { }
public bool IsHolidayRequestAlreadyCreated(string EmployeeId, DateTime DateFrom, DateTime DateTo)
{
return true;
}
}
我应该如何模拟此方法以使用来自 HolidayRequestRepository class 的逻辑?
问题是您没有测试代码的真实实现,而是测试了模拟代码。在单元测试中,您通常希望测试真正的实现。因此,在您的情况下,您必须创建 HolidayRequestRepository
的实例并在此对象上调用该方法,例如
var hrr = new HolidayRequestRepository(...);
var actual = hrr.IsHolidayRequestAlreadyCreated(empId, dtFrom, dtTo);
Assert.True(actual);
为了使其工作,您需要设置提供给构造函数的 DbContext,以便测试用例所需的数据可用。