【问题标题】:Mocking method dependency by type of context.Database.ExecuteSqlCommand in the unit test在单元测试中按 context.Database.ExecuteSqlCommand 的类型模拟方法依赖
【发布时间】:2016-11-12 12:59:36
【问题描述】:

我正在编写一个调用 FillInventory 方法的单元测试,在此方法中某些内容将在数据库中更新,在单元测试中我想通过调用 FillInventory 方法在数据库中更新前后检查数据中的某些内容并检查其输入.

为我服务:

public void FillInventory(InventoryViewModel invViewModel)
{

    long roomServiceId = invViewModel.RoomServiceId;
    var roomService = _unitOfWork.RoomServiceRepository.GetByID(roomServiceId);
    var placeId = roomService.Room.PlaceId;
    var capacity = roomService.Room.Capacity + roomService.ExtraCapacity;

    for (DateTime date = invViewModel.StartDate; date.Date < invViewModel.EndDate; date = date.AddDays(1))
    {
        var inv = _unitOfWork.InventoryRepository.GetByKey(invViewModel.RoomServiceId, date);
        if (inv != null)
        {
            inv.Price =(invViewModel.isUpdatingPrice)? invViewModel.Price:inv.Price;
            inv.BoardPrice = (invViewModel.isUpdatingBoardPrice) ? invViewModel.BoardPrice : inv.BoardPrice;
            inv.CertainAvailability = (invViewModel.isUpdatingCertainAvailability) ? invViewModel.CertainAvailability : inv.CertainAvailability;
            inv.FloatAvailability = (invViewModel.isUpdatingFloatAvailability) ? invViewModel.FloatAvailability : inv.FloatAvailability;
            inv.setWebServices(invViewModel.SellableWebServices.Select(sw => sw.Key).ToList());
        }
        else
        {
            var price = (invViewModel.isUpdatingPrice) ? invViewModel.Price : 0;
            var boardPrice = (invViewModel.isUpdatingBoardPrice) ? invViewModel.BoardPrice : 0;
            var certainAvailability = (invViewModel.isUpdatingCertainAvailability) ? invViewModel.CertainAvailability : 0;
            var floatAvailability = (invViewModel.isUpdatingFloatAvailability) ? invViewModel.FloatAvailability : 0;


            inv = new Jabama.Core.DataLayer.Models.Inventory(roomService, date, floatAvailability, certainAvailability,
                price, boardPrice);

            _unitOfWork.InventoryRepository.Insert(inv);
        }


    }
    _unitOfWork.Save();
    _unitOfWork.PlaceInfoRepository.UpdatePlaceInfos(placeId, capacity, invViewModel.StartDate, invViewModel.EndDate);
}

在我的仓库中

public class PlaceInfoRepository : GenericRepository<PlaceInfo>
{
    public PlaceInfoRepository(JabamaContext context):base(context)
    { }

    public void UpdatePlaceInfos(long placeId, int capacity, DateTime startDate, DateTime endDate)
    {
        var cmd = context.Database.Connection.CreateCommand();
        List<SqlParameter> p = new List<SqlParameter>();
        p.Add(new SqlParameter("@placeId", placeId));
        p.Add(new SqlParameter("@capacity",capacity));
        p.Add(new SqlParameter("@startDate", startDate.Date.ToString("yyyy -MM-dd")));
        p.Add(new SqlParameter("@endDate", endDate.Date.ToString("yyyy-MM-dd")));

        context.Database.ExecuteSqlCommand("exec UpdatePlaceInfo @placeId, @capacity, @startDate, @endDate", p.ToArray());
    }
}

我已经模拟了单元测试需要模拟的所有内容,但现在当存储库想要使用 context.Database.ExecuteSqlCommand 更新数据时出现问题。

如何模拟它?

【问题讨论】:

    标签: c# unit-testing stored-procedures mocking dbcontext


    【解决方案1】:

    无需模拟/伪造DbContext 及其成员 - 您只需模拟PlaceInfoRepository。

    您的目标是检查FillInventory calls the UpdatePlaceInfos with proper arguments - 不多不少:

    // Arrange
    var repositoryMock = new SomeMock<IPlaceInfoRepository>();
    ... // Setup mock for verification.
    var service = new Service(repositoryMock.Object);
    
    // Act
    service.FillInventory(vm);
    
    // Assert
    repositoryMock.Verify();
    

    其他任何东西,它更接近于模块集成测试,虽然在许多情况下很有用,但有时更难做到,而且通常比单个代码单元具有更大的范围。

    相关阅读-http://martinfowler.com/articles/mocksArentStubs.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-19
      • 2017-09-25
      • 2020-01-05
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2013-07-07
      • 2017-10-13
      相关资源
      最近更新 更多