测试重定向成功的控制器方法 - moq

时间:2014-03-06 15:49:33

标签: c# unit-testing moq

我们采取以下措施:

        mockSiteRepository.Setup(m => m.Sites).Returns(new Site[] {
            new Site {
                SiteID = 0,
                DateCreated = DateTime.Now,
                Name = "A",
                AddressID = 0
            }
        }.AsQueryable());

        mockAddressRepository.Setup(m => m.Addresses).Returns(new Address[] {
            new Address {
                AddressID = 0,
                Address1 = "A",
                Address2 = "B",
                CityID = 0,
                CountryID = 0,
                StateID = 0,
                ZIP = "D"
            }
        }.AsQueryable());

        SiteViewModel testForm = new SiteViewModel
        {
            SiteID = 0,
            DateCreated = DateTime.Now,
            Name = "A",
            AddressID = 0,
            Address1 = "E",
            Address2 = "F",
            CityID = 0,
            City = null,
            CountryID = 0,
            Country = null,
            StateID = 0,
            State = null,
            ZIP = "J"
        };


        SiteController controller = new SiteController(mockChemical.Object, mockSiteRepository.Object, mockChemicalRelationRepository.Object, mockAddressRepository.Object);

        ActionResult result = controller.Edit(testForm);

现在看一下Edit方法(伪):

    public ActionResult Edit(SiteViewModel siteViewModel)
    {
        if (ModelState.IsValid)
        {
            Address address = siteViewModel.Map();
            addressRepository.Edit(address);
            Site site = siteViewModel.Map(address.AddressID);
            siteRepository.Edit(site);

            TempData["success"] = string.Format("Site {0} was successfully edited", site.Name);
            return RedirectToAction("List");
        }
        else
        {
            // Something wrong with the values
        }
        return View(siteViewModel);
    }

你如何测试这种方法?

成功后,它会重定向到返回ViewResult的“List”控制器。我不想相信这只是因为它已经重定向,我的数据被成功编辑并保存......

所以我该怎么做才能检查一下,当我将SiteViewModel放入我的控制器方法时,它确实成功地编辑了现有网站。

1 个答案:

答案 0 :(得分:0)

在您创建MockBehaviour.StrictmockSiteRepository时使用mockAddressRepository

运行测试时,您应该会看到一个显示invocation of IAddressRepository.Edit(Site) failed with MockBehaviour.Strict的例外情况。现在您确切地知道在您的存储库中调用了哪些方法,因此您将知道它确实已经编辑了该站点。

然后你必须通过测试。在测试中设置模拟存储库以期望编辑。您不确切地知道将SiteAddress的哪个实例传递到您的模拟存储库,因此您必须使用It.Is< T>允许任何匹配实例的方法。像

这样的东西
mockSiteRepository.Setup(repo => repo.Save(It.Is<Site>(s => s.SiteID == testForm.SiteID)));

通过这种方式,您可以验证传递给存储库的内容至少具有正确的ID。


另一种解决这个问题的方法是使用It.IsAny&lt; T&gt;。方法,将站点分配给测试方法中的局部变量,然后在之后断言。我发现这会导致更多不言自明的错误消息并且更容易调试。例如:

//arrange
var mockSiteRepository = new Mock<ISiteRepository>();
var testForm = new Site { SiteID = 0 };

Site savedSite = null;
mockSiteRepository
    .Setup(repo => repo.Save(It.IsAny<Site>()))
    .Callback<Site>(s => savedSite = s);

//act
var controller = new SiteController(mockChemical.Object, mockSiteRepository.Object, mockChemicalRelationRepository.Object, mockAddressRepository.Object);
var result = controller.Edit(testForm);

//assert
Assert.That(savedSite, Is.Not.Null); //this verifies that your setup was called
Assert.That(savedSite.SiteID, Is.EqualTo(testForm.SiteID));
Assert.That(savedSite.Name, Is.EqualTo(testForm.Name));

//do your other asserts

//always VerifyAll at the end so you know your setups were all called
mockSiteRepository.VerifyAll();