我使用Ninject.Extensions.Mvc.FluentValidation包使用FluentValidation和Ninject建立了一个MVC Web项目。我直接跟踪了该软件包的文档。
我想编写一个验证此连线的自动化测试,并检查模型验证是否会按预期使用FluentValidation验证器。为了做到这一点,我很难在我的测试中调整正确的MVC应用程序。
基本上,我想充分启动MVC应用程序,以便创建Ninject内核,连接模型绑定器,并创建验证器。然后我想尝试通过MVC模型验证来验证实体,并确保显示来自验证器的预期消息。
自动测试Ninject,MVC和FluentValidation之间交互的最佳方法是什么?
答案 0 :(得分:2)
我有类似的设置,但我使用Unity代替Ninject。
我的IoC容器继承了UnityContainer,我在其中注册了所有的repos,validarots等。我受益于此,因为我有验证器具有repo依赖性(例如UserRegistrationValidator检查唯一用户名)。
我的IoC容器也实现了IValidatorFactory。我使用它注册一个像这样的全局ModelValidatorProvider:
var ioc = new IoCContainer();
ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(ioc));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
通过这个设置,我知道我的验证器将拦截控制器操作中的模型验证,但前提是验证器由ValidatorFactory解析。
所以基本上我有两组测试
通过这些我测试我的IoC容器是否可以解析模型的验证器。使用Unity,它看起来像这样:
// Arrange
var ioc = new IoCContainer();
// Assert
Assert.IsTrue(ioc.IsRegistered(IValidator<MyModel>));
如果您将所有模型都放在一个名称空间下,您甚至可以通过从特定名称空间获取所有类型来编写单个单元测试,并检查是否在循环中为它们注册了IValidator。
这些是测试我的(视图)模型的常用测试:
// Arrange
var validator = new MyModelValidator();
var model = new MyModel{ Name = null };
// Assert
validator.ShouldHaveValidationErrorFor(x => x.Name, model)
有了这个,就不需要旋转应用程序,只需测试你创建的内容。
希望这有帮助。
答案 1 :(得分:2)
我们在这里用于集成测试的是Selenium Webdriver,您可以使用NuGet获取它。我们编写代码page pattern,因此维护起来比较容易。
当我想检查是否有必要的字段或任何其他自定义验证时,我会执行以下操作:
[TestFixture]
public class CenterTests : TestBase
{
[Test]
public void CreateViewAndEditShouldWork()
{
S.OpenWithCI();
var loginPage = new LoginPage(S);
var homePage = loginPage.LoginValidUser("email", "Password");
var centerListPage = homePage.ClickCenterAndRoomLink();
var centerPage = centerListPage.ClickCreateLink();
//Create
centerPage.CreateInvalidCenter();
Assert.That(S.FindElement(By.CssSelector("span[for=Name]")).Text, Is.StringContaining(Strings.Error_Required));
Assert.That(S.FindElement(By.CssSelector("span[for=EnglishName]")).Text, Is.StringContaining(Strings.Error_Required));
centerListPage = centerPage.CreateValidCenter("Saguenay", "Sag", "2089 blv Talbot");
Thread.Sleep(2000);
S.ExpectSuccessNotice(Strings.CenterCreatedSuccessfully);
}
}
这是我的TestBase助手类的代码:
namespace Afi.AutomatedTests.Helpers
{
[TestFixture]
public class TestBase
{
protected IWebDriver S;
[SetUp]
public virtual void TestSetup()
{
S = new ChromeDriver();
S.Manage().Window.Size = new Size(1024, 768);
S.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
[TearDown]
public void TearDown()
{
S.Quit();
}
public string GetUrl(string relativePath)
{
if(!relativePath.StartsWith("/"))
throw new ArgumentException("Relative URL must begins with /");
return "http://afi.local" + relativePath;
}
}
}
所有这些测试都在其他项目中调用AutomatedTests,我可以像运行单元测试一样运行它们(resharper / nunit)。它使用Chromedriver进行测试。
如果您需要更多信息,请告诉我。