Контроллер модульного тестирования с сервисом и хранилищем для зависимостей - PullRequest
0 голосов
/ 15 марта 2012

У меня есть довольно стандартное приложение .NET MVC 3, которое использует Ninject для внедрения зависимостей.То, что я пытаюсь выполнить модульное тестирование, это представление, которое возвращается из контроллера.На нем есть контроллер с групповой службой, а служба имеет хранилище.Служба сначала проверяет, существует ли эта группа, и если она существует, возвращает false вместе с ошибкой.Затем контроллер проверяет логическое значение, чтобы определить, следует ли переместить пользователя в список групп или остаться на текущей странице и отобразить значение.

Контроллер

[HttpPost]
public ActionResult AddGroup(Group g)
{
   string error = string.Empty;
   if (groupService.Save(g, CurrentUser, out error))
   {
       return RedirectToAction("GetGroups");
   }
   else
   {
       ViewData["Error"] = error;
       return View("AddGroup");
   }
}

Сервис

[Inject]
public IGroupRepository CurrentGroupRepo { get; set; }

public bool Save(Group group, string username, out string error)
{
    error = string.Empty;
    var found = CurrentGroupRepo.GetGroup(group.Descr, false);
    if (found != null)
    {
        error = "That group alread exists";
        return false;
    }

    if (group.CreatedBy == null || group.CreatedBy == string.Empty)
    {
        group.CreatedBy = username;
        group.CreatedOn = DateTime.Now;
        group.IsDeleted =false;
    }

    group.ModifiedBy = username;
    group.ModifiedOn = DateTime.Now;

    try
    {
        if (group.GroupID == 0)
        {
            CurrentGroupRepo.AddGroup(group);
        }
        else
        {
            CurrentGroupRepo.UpdateGroup(group);
        }
        return true;
    }
    catch (Exception ex)
    {
        error = ex.Message + ex.StackTrace;
        return false;
    }
}

Модульный тест

[TestMethod]
public void TestAddGroup()
{
    // Arrange
    Mock<IUserService> uService = new Mock<IUserService>();
    Mock<IGroupService> gService = new Mock<IGroupService>();
    Mock<IObservationService> oService = new Mock<IObservationService>();
    Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>();

        string error = string.Empty;
        List<Group> groups = new List<Group>();
        Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false };
        Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>();

        mockGroupRepo.Setup(cr => cr.GetGroups(It.IsAny<bool>())).Returns(
            delegate {
                return groups;
            });
        mockGroupRepo.Setup(cr => cr.GetGroup(It.IsAny<string>(), It.IsAny<bool>())).Returns(
            delegate(Group _group) {
                return groups.Where(f => f.Descr == _group.Descr).FirstOrDefault();
            });
        mockGroupRepo.Setup(cr => cr.AddGroup(newGroup)).Returns(
            delegate {
                groups.Add(newGroup);
                return newGroup;
            });
        gService.SetupGet(d => d.CurrentGroupRepo).Returns(mockGroupRepo.Object);


    AdminController controller = new AdminController(gService.Object, uService.Object, oService.Object);
    Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false };
    var success = (ViewResult)controller.AddGroup(newGroup);
    Assert.IsTrue("GetGroups" == success.ViewName);

    var failure = (ViewResult)controller.AddGroup(newGroup);
    Assert.IsTrue("AddGroup" == failure.ViewName);
}

Я пытаюсь проверить, что при добавлении одной группы, он должен работать, а затем, когда я добавляю ту же группу, он должен перейти в другое представление.Но прямо сейчас, модульный тест использует реальный репозиторий вместо смоделированного.Как получить, чтобы репозиторий в смоделированной службе контролировался модульным тестом, вместо того, чтобы фактически использовать реальный репозиторий?

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Если вы проводите модульное тестирование контроллера, вам не нужно беспокоиться о репозитории, потому что ваша служба имитируется. Что касается контроллера, то репозитория нет, все, о чем он знает, это контракт IGroupService.

Я не вижу, как ваш тест использует реальный репозиторий с учетом предоставленного вами кода. Если вы хотите изменить результат теста, вам нужно будет предоставить несколько поддельных ответов на ваш макет IGroupService.

Вам потребуется второй модульный тест для GroupService, который принимает в Mocked Repository.

ИМО модульный тест должен проверять только один класс, все остальное должен быть либо издеваться, либо быть очень простым объектом. Если ты делать больше, тогда это интеграционный тест.

0 голосов
/ 15 марта 2012

Я немного упростил это, учитывая совет Бронумски.Вот код, и все, кажется, снова работает хорошо.

        [TestMethod]
    public void TestAddGroup() {
        // Arrange
        Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false };
        gService.Setup(cr => cr.Save(It.IsAny<Group>(), It.IsAny<string>())).Returns("");

        AdminController controller = new AdminController(gService.Object, uService.Object, oService.Object);

        // Act 
        var success = (RedirectToRouteResult)controller.AddGroup(newGroup);
        Assert.IsTrue("GetGroups" == success.RouteValues["action"].ToString());

        gService.Setup(cr => cr.Save(It.IsAny<Group>(), It.IsAny<string>())).Returns("Error");
        var failure = (ViewResult)controller.AddGroup(newGroup);
        Assert.IsTrue("AddGroup" == failure.ViewName);
    }
...