4

Ninject.Extensions.Mvc.FluentValidation パッケージを使用して、FluentValidation と Ninject で MVC Web プロジェクトをセットアップしました。そのパッケージのドキュメントを直接たどりました。

この配線を検証し、モデルの検証が FluentValidation バリデーターを期待どおりに使用することを確認する自動テストを作成したいと思います。これを行うために、テストで MVC アプリケーションの適切な部分をスピンアップするのに苦労しています。

基本的に、Ninject カーネルが作成され、モデル バインダーが接続され、バリデータが作成されるように、MVC アプリを十分にスピンアップしたいと考えています。次に、MVC モデルの検証を通じてエンティティを検証し、バリデーターからの期待されるメッセージが表示されていることを確認したいと考えています。

Ninject、MVC、および FluentValidation 間の相互作用のテストを自動化する最良の方法は何ですか?

4

2 に答える 2

2

私も同様の設定をしていますが、Ninjectの代わりにUnityを使用しています。

私のIoCコンテナはUnityContainerを継承し、すべてのリポジトリ、バリデーターなどを登録します。リポジトリに依存するバリデーターがあるため、これから恩恵を受けます(たとえば、UserRegistrationValidatorは一意のユーザー名をチェックします)。

私のIoCコンテナはIValidatorFactoryも実装しています。私はそれを使用して、次のようなグローバルModelValidatorProviderを登録します。

var ioc = new IoCContainer();
ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(ioc));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

この設定では、バリデーターがValidatorFactoryによって解決された場合にのみ、バリデーターがコントローラーアクションでモデル検証をインターセプトすることを知っています。

だから基本的に私は2つのグループのテストを持っています

-IoCテスト

これらを使用して、IoCコンテナがモデルのバリデーターを解決できるかどうかをテストします。Unityを使用すると、次のようになります。

// Arrange
var ioc = new IoCContainer();

// Assert
Assert.IsTrue(ioc.IsRegistered(IValidator<MyModel>));

すべてのモデルが1つの名前空間にある場合は、特定の名前空間からすべての型を取得して単一の単体テストを記述し、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 に答える
2

ここで統合テストに使用するのはSeleniumWebdriverで、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 に答える