C#使用Moq模拟通用存储库

时间:2018-01-19 09:55:00

标签: c# unit-testing generics moq

我在我的项目中实现了通用存储库。现在我正在为我的消费者编写测试用例。我试图通过Moq模拟数据库功能,但我从数据库获取值而不是我通过Moq伪造的。下面我分享我的实施。希望有人帮助我指出我犯的错误。

我的界面:

public interface IEventsRepository<T> : IRepository<T>  {

T GetEventsByEventId(int eventId);  }

我的课程:

public class EventsTableRepository : EFDBRepository<EventsModel>, IEventsRepository<EventsModel>  {
public EventsModel GetEventsByEventId(int eventId)
{
  return _dbSet.Where(x => x.EventID == eventId).FirstOrDefault();
}

}

我的消费者:

public static Response<string> EventsAccept(EventsAlertsRequest logMsgId)
{
  IEventsRepository<EventsModel> eventsRepo = (IEventsRepository<EventsModel>)RepositoryLocator.GetRepositoryObject(STMEnums.RepositoryName.EventsTableRepository.ToString());
  EventsModel eventmodel = new EventsModel();
  eventmodel = eventsRepo.GetEventsByEventId(eachlogMsgId);
  return EventStatusChangeResponse;
}

测试方法:

public void EventsAcceptSuccessTest()
    {
        EventsModel eventmodel = new EventsModel();
        eventmodel.Message = "TEST";

        Mock<IEventsRepository<EventsModel>> obj = new Mock<IEventsRepository<EventsModel>>();
        obj.Setup(m => m.GetEventsByEventId(Moq.It.IsAny<int>())).Returns(eventmodel);

        EventStatusChangeResponse = Diagnostics_.EventsAccept(logMsgId);            
        Assert.AreEqual(eventmodel.Status, EventStatus.ACCEPTED);
    }

1 个答案:

答案 0 :(得分:1)

否则在提供的示例中,模拟被注入被测试对象。此外,它看起来像测试中的主题方法是使用静态服务定位器反模式来获得所需的模型。 在此处作出假设,因为该类的其余部分未与该变量相关。

定位器需要一个注入的抽象,以便有机会模拟其预期的行为

public class Consumer {
    private IRepositoryLocator RepositoryLocator;

    public Consumer(IRepositoryLocator RepositoryLocator) {
        this.RepositoryLocator = RepositoryLocator;
    }

    public Response<string> EventsAccept(EventsAlertsRequest logMsgId) {
      IEventsRepository<EventsModel> eventsRepo = (IEventsRepository<EventsModel>)RepositoryLocator.GetRepositoryObject(STMEnums.RepositoryName.EventsTableRepository.ToString());
      EventsModel eventmodel = new EventsModel();
      eventmodel = eventsRepo.GetEventsByEventId(eachlogMsgId);
      return EventStatusChangeResponse;
    }
}

这就意味着定位器也必须被适当地模拟才能完成测试。

public void EventsAcceptSuccessTest() {
    //Arrange
    var eventmodel = new EventsModel() {
        Message = "TEST"
    };

    var repositoryMock = new Mock<IEventsRepository<EventsModel>>();
    repositoryMock
        .Setup(_ => _.GetEventsByEventId(It.IsAny<int>()))
        .Callback((int id) => {
            eventmodel.EventID = id;
            eventmodel.Status = EventStatus.ACCEPTED;
        })
        .Returns(eventmodel);

    var locatorMock = new Mock<IRepositoryLocator>();
    locatorMock.Setup(_ => _.GetRepositoryObject(It.IsAny<string>())).Returns(repositoryMock.Object);

    var subject = new Consumer(locatorMock.Object);

    //Act
    var response = subject.EventsAccept(logMsgId);

    //Assert
    Assert.AreEqual(eventmodel.Status, EventStatus.ACCEPTED);
}