0

私は MSpec を初めて使用し、ASP.NET MVC のテストを記述した方法が正しいかどうかを知りたいです。テストはパスしましたが、書き方が気に入らず、ぎこちなく見えます。私は確かに何かが欠けています。

public class AccountControllerTests3
{
    protected static AccountController controller;
    static IFormsAuthenticationService formsService;
    static IMembershipService membershipService;
    protected static ActionResult result;
    protected static LogOnModel model;

    Establish context = () =>
    {
        var controllerBuilder = new TestControllerBuilder();

        formsService = MockRepository.GenerateStub<IFormsAuthenticationService>();
        membershipService = MockRepository.GenerateStub<IMembershipService>();
        model = MockRepository.GenerateStub<LogOnModel>();

        controller =
            controllerBuilder.CreateController<AccountController>(new object[]
                                                                    {
                                                                        formsService,
                                                                        membershipService
                                                                    });
    };

    Because user_logs = () =>
    {
        bool rememberMe = false;

        membershipService.Stub(
            x => x.ValidateUser("bdd", "mspec")).Return(true);
        formsService.Stub(x => x.SignIn("bdd", rememberMe));

        controller.ModelState.IsValid.ShouldBeTrue();
    };
}

[Subject(typeof(AccountController), "LogInTests")]
public class When_logging_into_application_with_good_login_and_password : AccountControllerTests3
{
    private It user_should_be_redirected_to_the_home_page = () =>
                                                                {
                                                                    model.UserName = "bdd";
                                                                    model.Password = "mspec";

                                                                    result = controller.LogOn(model, string.Empty);

                                                                    result.AssertActionRedirect().ToAction<HomeController>(
                                                                        x => x.Index());
                                                                };
}

[Subject(typeof(AccountController), "LogInTests")]
public class When_logging_into_application_with_bad_login_and_password : AccountControllerTests3
{
    It The_error_message_should_be_shown = () =>
                                            {
                                                model.UserName = "BAD";
                                                model.Password = "BAD";

                                                result = controller.LogOn(model, string.Empty);

                                                controller.ModelState[""].Errors[0].ErrorMessage.ShouldEqual(
                                                    "The user name or password provided is incorrect.");
                                            };
}

前もって感謝します、

トーマス

4

2 に答える 2

4

MSpec でテストを作成するときの目標の 1 つは、「Assert」または「It」を 1 行にまとめることです。MSpec は、Context (現在のクラスとすべての基本クラスの Establish 句、Because 句で構成される) を一度だけ実行し、その後にすべての仕様 (It 句) を実行するという点で、NUnit とは異なります。

これは、It 句で動作を実行せず、観察することを明示的に強制するように設計されています。

ここで実際に行っているのは、NUnit のような MSpec を使用することです。(継承を使用せずに) 単一のクラスでテストを書き直してみてください。さかのぼって... It に、主張したいことを主張する 1 行を配置します。おそらくAssertRedirect. 原因には、観測を観察可能にする1行を入れてみてください。これはおそらく、コントローラーのログオン メソッドへの呼び出しです。最後に、「Establish context」に他のすべてを配置します。

しばらくすると、Establish コンテキスト内のものの一部を基本クラスのみにプルしたい場合がありますが、その際、サブクラス全体が理解の点で独立していることを確認してください。実際の仕様が何をしているかを理解するために、基本クラスを読む必要はありません。儀式的な実装の詳細を隠しても問題ありませんが、説明的なメソッド名の背後に隠してください。

よくわからない別の行があります:

controller.ModelState.IsValid.ShouldBeTrue();

これがテストの場合は、おそらくそれ自体の It 句にあるはずです。本当に、これをテストしますか? ここで何をテストしていますか?モデルが有効であるかどうかに基づいて、コントローラがアクションを実行するべきではありませんか? そのアクションの結果が観察可能であってはなりません (ログイン エラーではなく検証エラー)。本当にこれをテストする必要があるのだろうか。

最初に R# を使用したスタイリングについて確認する必要がある他のいくつかのことは、テストが R# のデフォルトの犠牲になっているようです。ここにこれと戦う方法について投稿しました:

http://codebetter.com/blogs/aaron.jensen/archive/2008/10/19/getting-resharper-and-vs-to-play-nice-with-mspec.aspx

また、James Broome には、チェックする価値のある素敵な MVC MSpec 拡張機能がいくつかあります。

http://jamesbroo.me/introducing-machinespecificationsmvc/

頑張って楽しんでください!他に関係のない質問がある場合は、Twitter でお気軽にお問い合わせください。

于 2010-02-05T16:45:02.387 に答える
1

CreateControllerここに注意があります:メソッド useを使用する代わりに、InitializeControllerコンパイル時の安全性が高く、リファクタリングしやすいためです。

それ以外の:

controller = controllerBuilder.CreateController<AccountController>(
    new object[] { formsService, membershipService });

行う:

controller = new AccountController(formsService, membershipService);
controllerBuilder.InitializeController(controller);

コントローラーのコンストラクターの引数を変更すると、最初のコードはコンパイルされ、実行時に失敗しますが、2 番目のコードはコンパイル時エラーを生成します。

于 2010-02-05T10:56:21.673 に答える