Question

Je suis nouveau à MSpec et voudrais savoir si la façon dont je l'ai écrit mon test pour ASP.NET MVC est correcte. Le test passe mais je ne aime pas vraiment la façon dont il est écrit et il semble maladroit. Je ne suis certainement manque quelque chose.

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.");
                                            };
}

Merci à l'avance,

Thomas

Était-ce utile?

La solution

L'un de mes objectifs quand j'écris des tests avec MSpec est d'obtenir le « Assertion » ou « Il » vers le bas à une ligne. MSpec est pas comme NUnit en ce qu'elle exécute uniquement le contexte (composé des clauses de la Mettre en place des classes en cours et toutes les classes de base et la clause Parce que) une fois suivie par toutes les spécifications (clauses It).

est explicitement conçu pour vous forcer à ne pas effectuer tout comportement dans les clauses, mais plutôt observer.

Qu'est-ce que vous faites en fait ici utilise MSpec comme NUnit. Essayez de réécrire les essais en une seule classe (en utilisant pas d'héritage). Travailler en arrière ... dans le, placez une seule ligne qui affirme ce que vous voulez faire valoir. Peut-être le assertRedirect. Dans les Parce que, essayer de mettre une ligne que Causes les observations à observer. Ce serait probablement votre appel à la méthode de connexion du contrôleur. Enfin, dans le « Établir le contexte » que vous voudriez mettre tout le reste.

Après un certain temps, vous voudrez peut-être tirer quelques-unes des choses dans le établir le contexte uniquement dans une classe de base, mais ce faisant, assurez-vous que votre sous-classe entière est le seul en termes de compréhension . Un lecteur ne devrait pas avoir besoin de lire la classe de base afin de comprendre ce que la spécification réelle est en train de faire. Il est autorisé à cacher les détails de mise en œuvre de cérémonie, mais assurez-vous de les cacher derrière des noms de méthode descriptive.

Il y a une autre ligne Je ne suis pas sûr:

controller.ModelState.IsValid.ShouldBeTrue ();

Si ceci est un test, il devrait probablement être dans sa propre clause It. Bien que vraiment, voulez-vous tester cela? Qu'est-ce que vous testez ici? Ne devrait pas prendre votre contrôleur une action en fonction ou non le modèle est valide? Ne devrait pas le résultat de cette action soit (erreur de validation au lieu d'une erreur de connexion) observable. Je me demande si vous avez vraiment besoin de tester ce .

Quelques autres choses à vérifier, d'abord pour un style avec R #, il semble que vos tests sont, victimes de défaut de R #. Je posté sur la façon de lutter contre ce ici:

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

En outre, James Broome a quelques extensions belles MVC MSpec qui sont la peine de vérifier:

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

Bonne chance et bonne chance! Ne hésitez pas à me ping sur twitter si vous avez d'autres questions sans rapport.

Autres conseils

Voici une remarque: au lieu d'utiliser la méthode de l'utilisation CreateController InitializeController, car il est la compilation plus sûre et refactoriser plus convivial.

Au lieu de:

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

Do:

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

La première sera toujours compiler si vous modifiez les arguments du constructeur du contrôleur et il soufflera lors de l'exécution, tandis que le second génère une erreur de compilation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top