模拟具有存储库接口属性的UnitOfWork接口

时间:2018-11-01 09:56:38

标签: c# unit-testing moq mstest

我正在实现单元测试以测试助手类中的方法。
我已经模拟了IRepository接口,并将其对象传递给了模拟的IUnitOfWork,因为此IRepository接口是UnitOfWork的属性。在调试单元测试时,我发现对helper类中的'_unitOfWork.Booking.OverlappingBooking'的调用始终返回null。完全不调用OverlappingBooking()。

public class BookingHelper
    {
        private IUnitOfWork _unitOfWork;

        public BookingHelper(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public string OverlappingBookingsExist(Booking booking)
        {
            if (booking.Status == "Cancelled")
                return string.Empty;

            var bookings = _unitOfWork.Booking.GetActiveBookings<Booking>().Where(
                        b => b.Id != booking.Id && b.Status != "Cancelled"); 

            var overlappingBooking = _unitOfWork.Booking.OverlappingBooking(bookings, booking);


            return overlappingBooking;
        }
    }

我的UnitOfWork

 public interface IUnitOfWork
    {
        IBookingHelperRepository Booking { get; set; }
    }
    public class UnitOfWork: IUnitOfWork
    {

        public IBookingHelperRepository Booking { get; set; }

        public UnitOfWork()
        {
            Booking = new BookingHelperRepository();
        }

    }

存储库

public interface IBookingHelperRepository
    {
        IQueryable<T> GetActiveBookings<T>();

        string OverlappingBooking(IQueryable<Booking> bookings, Booking booking);
    }


    public class BookingHelperRepository: IBookingHelperRepository
    {
        public IQueryable<T> GetActiveBookings<T>()
        {
            var resp = new List<T>().AsQueryable();

            return resp;
        }

        public string OverlappingBooking(IQueryable<Booking> bookings, Booking booking)
        {
          var overlappingBooking =  bookings.FirstOrDefault(
                    b => booking.ArrivalDate >= b.ArrivalDate
                        && booking.ArrivalDate < b.DepartureDate
                        || booking.DepartureDate > b.ArrivalDate
                        && booking.DepartureDate <= b.DepartureDate);

            return overlappingBooking == null ? string.Empty : overlappingBooking.Reference;
        }
    }

我已经按照以下步骤设置了我的测试课程。

 [TestClass]
    public class BookingHelperTests
    {
 private Mock<IBookingHelperRepository> bookingHelperRepository;
 private BookingHelper bookingHelper;
 private Booking booking;
 private Mock<IUnitOfWork> unitOfWork;
 [TestInitialize]
        public void Initialise()
        {
            unitOfWork = new Mock<IUnitOfWork>();
            bookingHelper = new BookingHelper(unitOfWork.Object);
            bookingHelperRepository = new Mock<IBookingHelperRepository>();
            .....
        }

 [TestMethod]
        public void OverlappingBookingsExist_BookingStartsAndFinishesBeforeAnExistingBooking_ShouldReturnEmptyString()
        {
            bookingHelperRepository.Setup(y => y.GetActiveBookings<Booking>()).Returns(bookingListBefore.AsQueryable());
            unitOfWork.Setup(x => x.Booking).Returns(bookingHelperRepository.Object);

            //Act
            var result = bookingHelper.OverlappingBookingsExist(booking);

            //Assert
            Assert.AreEqual("", result);
        }

1 个答案:

答案 0 :(得分:0)

您要测试的代码调用(IBookingHelperRepository)(IUnitOfWork.Booking).OverlappingBooking(),您不会嘲笑。由于模拟默认情况下是宽松的,因此它们返回null而不是引发异常。

如果您用new Mock<IBookingHelperRepository>()设置了MockBehavior.Strict,则会收到一个异常消息,告诉您尚未设置方法string OverlappingBooking(IQueryable<Booking> bookings, Booking booking)

为此:

var queryableBookings = bookingListBefore.AsQueryable();
bookingHelperRepository.Setup(y => y.GetActiveBookings<Booking>()).Returns(queryableBookings);
bookingHelperRepository.Setup(y => y.OverlappingBooking(queryableBookings, booking).Returns(booking.Reference);