Question

Je suis en train d'apprendre Rhino Mocks syntaxe AAA, et je vais avoir du mal à faire valoir une certaine méthode (avec une valeur d'argument) a été appelé. J'utilise Machine.Specifications comme mon framework de test.

Cette méthode particulière est générique et je veux vous assurer qu'il a été appelé trois fois avec trois types différents.

repo.Save<T1>(anything), repo.Save<T2>(anything), and repo.Save<T3>(anything)

J'écrasa la fonction pour chaque type. Mais je reçois un résultat intéressant. (Ci-dessous)

[Subject("Test")]
public class When_something_happens_with_constraint
{
    static IRepository repo;
    static TestController controller;
    static ActionResult result;

    Establish context = () =>
    {
        repo = MockRepository.GenerateMock<IRepository>();
        controller = new TestController(repo);
        repo.Stub(o => o.Save<Something>(Arg<Something>.Is.Anything));
        repo.Stub(o => o.Save<SomethingElse>(Arg<SomethingElse>.Is.Anything));
        repo.Stub(o => o.Save<AnotherOne>(Arg<AnotherOne>.Is.Anything));
    };

    //post data to a controller
    Because of = () => { result = controller.SaveAction(new SomethingModel() { Name = "test", Description = "test" }); };

    //controller constructs its own something using the data posted, then saves it. I want to make sure three calls were made.  
    It Should_save_something = () => repo.AssertWasCalled(o => o.Save<Somethign>(Arg<Something>.Is.Anything));
    It Should_save_something_else = () => repo.AssertWasCalled(o => o.Save<SomethingElse>(Arg<SomethingElse>.Is.Anything));
    It Should_save_another_one = () => repo.AssertWasCalled(o => o.Save<AnotherOne>(Arg<AnotherOne>.Is.Anything));
}

Le résultat est deux exceptions et un laissez-passer.

Le premier appel lance:

  

System.InvalidOperationException: attentes Aucun ont été installés à vérifier, assurez-vous que l'appel de méthode dans l'action est un appel de méthode virtuelle (C #) / Overridable (VB.Net)

Le second jette:

  

System.InvalidOperationException: Utilisez Arg uniquement dans un appel de méthode d'enregistrement maquette en. 1 arguments attendus, 2 ont été définis.

La troisième passe ... pour une raison étrange.

Je l'ai également essayé d'utiliser GenerateMock () avec Attendez-vous dans ma configuration, ainsi que l'utilisation GenerateStub () avec Stub. Les deux se sont retrouvés avec le même résultat exact. Je dois y être en train de faire quelque chose de mal.

J'utilise: MachineSpec 0.3.0.0 et 3.6.0.0 RhinoMocks

Toutes les idées?

----- ---------- FIXE

Voici la complète (version de travail) avec l'aide de Lee. J'utilise une couche supplémentaire (non LINQ). Mon problème réel est que l'un de mes tests RÉUTILISÉS la mauvaise variable lambda dans le code réel hors ligne.     Il Should_do_something = () => repo.AssertWasCalled ( o => repo .Save (données)); // mauvais lambda

Alors, voici un échantillon du test correct pour référence.

using System;
using System.Linq;
using System.Collections.Generic;
using Machine.Specifications;
using Rhino.Mocks;

namespace OnlineTesting.Specifications
{
    public interface Repository
    {
        void Save<T>(T data);
        IQueryable<T> All<T>();
    }

    public interface Service
    {
        void SaveItem(Item data);
        void SaveAnotherItem(AnotherItem data);
        void SaveOtherItem(OtherItem data);
        List<Item> GetItems();
        List<AnotherItem> GetAnotherItems();
        List<OtherItem> GetOtherItems();
    }

    public class ConcreteService : Service
    {
        Repository repo;
        public ConcreteService(Repository repo)
        {
            this.repo = repo;
        }
        public void SaveItem(Item data)
        {
            repo.Save(data);
        }
        public void SaveAnotherItem(AnotherItem data)
        {
            repo.Save(data);
        }
        public void SaveOtherItem(OtherItem data)
        {
            repo.Save(data);
        }

        public List<Item> GetItems()
        {
            return repo.All<Item>().ToList();
        }
        public List<AnotherItem> GetAnotherItems()
        {
            return repo.All<AnotherItem>().ToList();
        }
        public List<OtherItem> GetOtherItems()
        {
            return repo.All<OtherItem>().ToList();
        }
    }

    public class Item
    {
        public int Id { get; set; }
    }
    public class OtherItem
    {
    }
    public class AnotherItem
    {
    }


    public class When_something_else_happens
    {
        Establish context = () =>
        {
            _repository = MockRepository.GenerateMock<Repository>();
            _service = new ConcreteService(_repository);
            _controller = new TestController(_service);

            _repository.Stub(o => o.Save<Item>(Arg<Item>.Is.Anything)).WhenCalled(
                new Action<MethodInvocation>((o) =>
                {
                    var data = o.Arguments.FirstOrDefault() as Item;
                    if (data != null && data.Id == 0)
                        data.Id++;
                }));
        };

        Because of = () => _controller.DoSomethingElse();

        It should_save_the_first_thing = () =>
             _repository.AssertWasCalled(repo => repo.Save(Arg<Item>.Is.Anything));

        It should_save_the_other_thing = () =>
             _repository.AssertWasCalled(repo => repo.Save(Arg<OtherItem>.Is.Anything));

        It should_save_the_last_thing = () =>
             _repository.AssertWasCalled(repo => repo.Save(Arg<AnotherItem>.Is.Anything));

        static Repository _repository;
        static TestController _controller;
        static Service _service;
    }

    public class TestController
    {
        readonly Service _service;

        public TestController(Service service)
        {
            _service = service;
        }

        public void DoSomethingElse()
        {
            _service.SaveItem(new Item());
            _service.SaveOtherItem(new OtherItem());
            _service.SaveAnotherItem(new AnotherItem());
        }
    }
}
Était-ce utile?

La solution

pour cette solution.

[Subject("Test")]
public class When_something_happens_with_constraint
{
    static IRepository repo;
    static TestController controller;
    static ActionResult result;

    Establish context = () =>
    {
        repo = MockRepository.GenerateMock<IRepository>();
        controller = new TestController(repo);
    };

    //post data to a controller
    Because of = () => result = controller.SaveAction(new SomethingModel() { Name = "test", Description = "test" });

    //controller constructs its own something using the data posted, then saves it. I want to make sure three calls were made.  
    It Should_save_something = () => repo.AssertWasCalled(o => o.Save(Arg<Something>.Is.Anything));
    It Should_save_something_else = () => repo.AssertWasCalled(o => o.Save(Arg<SomethingElse>.Is.Anything));
    It Should_save_another_one = () => repo.AssertWasCalled(o => o.Save(Arg<AnotherOne>.Is.Anything));
}

Autres conseils

Le point que tout le monde semble être au-dessus de lustrage est que vous ne pas besoin de talon afin d'effectuer une « assert a été appelé ». Et, comme vous l'avez écrit, Arg<T>.Is.Anything, il va ignorer le type. Vous n'êtes pas vérifier des contraintes génériques. Vous voulez utiliser Arg<T>.Is.TypeOf<T>. Consultez la documentation pour plus de détails.

-----------------------------------------------
| Arg<T>.Is   |                               |
===============================================
| Anything()  | No constraints                |
-----------------------------------------------
| TypeOf<T>() | Argument is of a certain type |
-----------------------------------------------

fixe extrait de code est encore trop compliqué. Vous n'utilisez pas l'objet data que vous enregistrez dans le « lorsqu'il est appelé ». Et vous n'avez pas besoin de faire un simple « assert a été appelé ».

@ le code de leebrandt regards comme correct et simple que cela, sans introduire un récipient automocking.

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