4

我已经使用 Ninject.Extensions.Mvc.FluentValidation 包设置了一个带有 FluentValidation 和 Ninject 的 MVC Web 项目。我直接遵循了该包的文档。

我想编写一个自动化测试来验证此接线,并检查模型验证是否将按预期使用 FluentValidation 验证器。为了做到这一点,我很难在测试中启动 MVC 应用程序的正确部分。

基本上,我想启动 MVC 应用程序,以便创建 Ninject 内核、连接模型绑定器并创建验证器。然后我想尝试通过 MVC 模型验证来验证实体,并确保显示来自验证器的预期消息。

自动化测试 Ninject、MVC 和 FluentValidation 之间交互的最佳方法是什么?

4

2 回答 2

2

我们这里用于集成测试的是Selenium Webdriver,你可以通过 NuGet 获得它。我们编写代码使用页面模式,因此更易于维护。

当我想检查是否需要字段或任何其他自定义验证时,我会执行以下操作:

    [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 进行测试。

如果您需要更多信息,请告诉我。

于 2013-03-06T22:36:08.180 回答
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)

这样就不需要旋转应用程序,您只需测试您创建的内容。

希望这可以帮助。

于 2013-03-06T22:20:52.360 回答