C# 测试成功时重定向的控制器方法-moq
让我们采取以下措施:C# 测试成功时重定向的控制器方法-moq,c#,unit-testing,moq,C#,Unit Testing,Moq,让我们采取以下措施: mockSiteRepository.Setup(m => m.Sites).Returns(new Site[] { new Site { SiteID = 0, DateCreated = DateTime.Now, Name = "A", AddressID = 0 }
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);
现在看一下编辑方法(伪):
你如何测试这种方法
成功后,它重定向到“列表”控制器,该控制器返回ViewResult。我不想仅仅因为它已重定向而相信它,我的数据已成功编辑和保存
那么,当我将SiteViewModel放入控制器方法中时,如何检查它是否确实成功编辑了现有站点。使用
mockbehavior.Strict
创建mockSiteRepository
和mockAddressRepository
时
当您运行测试时,您应该会看到一个异常,该异常表示您调用IAddressRepository.Edit(Site)失败,MockBehavior.Strict。现在您确切地知道在存储库中调用了哪些方法,这样您就知道它确实编辑了站点
然后你必须通过测试。在测试中设置模拟存储库以期望编辑。您不知道站点
或地址
的哪个实例将被传递到您的模拟存储库,因此您必须使用It.is方法来允许任何匹配实例。差不多
mockSiteRepository.Setup(repo => repo.Save(It.Is<Site>(s => s.SiteID == testForm.SiteID)));
mockSiteRepository.Setup(repo=>repo.Save(It.Is(s=>s.SiteID==testForm.SiteID));
通过这种方式,您可以验证传递到存储库的内容至少具有正确的ID
另一种方法是使用It.IsAny方法,在测试方法中将站点分配给一个局部变量,然后对其进行断言,我发现这种方法更可靠。我发现这会导致更多不言自明的错误消息和更容易的调试。例如:
//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();
//排列
var mockSiteRepository=new Mock();
var testForm=新站点{SiteID=0};
Site savedSite=null;
mockSiteRepository
.Setup(repo=>repo.Save(It.IsAny()))
.Callback(s=>savedSite=s);
//表演
var controller=新站点控制器(mockChemical.Object、mockSiteRepository.Object、mockChemicalRelationRepository.Object、mockAddressRepository.Object);
var结果=controller.Edit(testForm);
//断言
Assert.That(savedSite,Is.Not.Null)//这将验证是否调用了安装程序
Assert.That(savedSite.SiteID,Is.EqualTo(testForm.SiteID));
Assert.That(savedSite.Name,Is.EqualTo(testForm.Name));
//你还有其他主张吗
//始终在最后验证所有设置,以便您知道所有设置都已调用
mockSiteRepository.VerifyAll();
那么您要检查的是什么?是否调用了repository Edit()方法?如果能使用我的addressRepository.Edit(地址)和siteRepository.Edit(站点)正确修改我最初从mockSiteRepository/mockAddressRepository获得的假模型,那就太好了;我可以通过断言新的存储库模型将等同于testForm SiteViewModel来测试这一点。也许这比我原来想的要复杂得多?我会尽快尝试的。谢谢你的时间,兄弟!别担心,让我知道你进展如何。@JoeTaylor虽然不适用于你的场景,但值得一提的是,有时你可能需要设置模拟的各种方法来支持被测试的类,但你不一定要验证它们是否都被调用了。因此,您不必使用.VerifyAll
,而可以。验证特定的方法和属性,查看它们是否被访问(甚至被访问了多少次)。我脑海中浮现出类似于mockSiteRepository.Verify(repo=>repo.Save(It.IsAny())、Times.Once()的东西例如,code>。@AndrewStephens我完全同意,尤其是当您在多个测试用例之间使用共享设置方法时。对我来说,它归结为如何使阅读者尽可能清楚地理解测试的意图,而不引入重复。
//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();