Question

Je développe une application asp.net (classique) qui tente d'implémenter le modèle MVP en utilisant cet exemple . En essayant de tester un peu mon présentateur et en utilisant le modèle suivant, le psuedocode pour lequel ressemble tellement

//base view interface
public interface IView
{
    event EventHandler Init;

    event EventHandler Load;

    bool IsPostBack { get; }

    void DataBind();

    bool IsValid { get;}
}

//presenter psuedo code
public class SomePresenter
{
     public SomePresenter(ISomeDomainService service, IView someView)
     {
           ...
           //HOW DO WE TEST/VERIFY THAT THIS REGISTRATION OCCURS?
           someView.Init += OnInit;
           someView.Load += OnLoad;
     }
}
...
//consuming code that exercises the above code, that needs to be tested
var presenter = new SomePresenter(someDomainService, someView);

Comment puis-je vérifier que le présentateur accomplit ce qui est attendu, c’est-à-dire s’inscrire aux événements Init et Load? Bien que cela se fasse facilement dans l'exemple de Phil Haack avec Rhino se moque ...

[Test]
public void VerifyAttachesToViewEvents()
{
    viewMock.Load += null;
    LastCall.IgnoreArguments();
    viewMock.PostSaved += null;
    LastCall.IgnoreArguments();
    mocks.ReplayAll();
    new PostEditController(viewMock, 
      this.dataServiceMock);
    mocks.VerifyAll();
}

... comment pouvons-nous faire cela en utilisant MOQ?

Était-ce utile?

La solution

Il semblerait que cette fonctionnalité soit non disponible actuellement . en moq, mais peut apparaître dans une future version (j’ai jeté un œil à la version bêta de 4.0.812.4, mais elle ne semble pas être là).

Il peut être utile de poser la question suivante: & "Pourquoi SomePresenter devez-vous vous abonner aux événements de la vue Load et Init? &"; C'est probablement parce que la classe Raise doit réagir à ces événements. Il pourrait donc être préférable d’utiliser la méthode Mock<IView> sur vos <=> pour générer les événements <=> et <=>, puis d’affirmer que <=> a bien agi en réponse.

Autres conseils

Je sais qu'il est peut-être trop tard pour #Dilip, mais cette réponse peut être utile pour ceux qui essaient de faire de même. Voici la classe de test

public delegate void SubscriptionHandler<T>(string name, T handler);

public class SomePresenterTest
{
    [Test]
    public void Subscription_Test()
    {
        var someServiceMock = new Mock<ISomeDomainService>();
        var viewMock = new Mock<IView>();
        //Setup your viewMock here

        var someView = new FakeView(viewMock.Object);
        EventHandler initHandler = null;            
        someView.Subscription += (n, h) => { if ((nameof(someView.Init)).Equals(n)) initHandler=h; };

        Assert.IsNull(initHandler);

        var presenter = new SomePresenter(someServiceMock.Object, someView);

        Assert.IsNotNull(initHandler);
        Assert.AreEqual("OnInit", initHandler.Method?.Name);
    }
}

FakeView est un décorateur implémenté comme suit (faites attention aux événements: Init / Load {add; remove}):

public class FakeView : IView
{
    public event SubscriptionHandler<EventHandler> Subscription;
    public event SubscriptionHandler<EventHandler> Unsubscription;
    private IView _view;
    public FakeView(IView view)
    {
        Assert.IsNotNull(view);
        _view = view;
    }

    public bool IsPostBack => _view.IsPostBack;
    public bool IsValid => _view.IsValid;

    public event EventHandler Init
    {
        add
        {
            Subscription?.Invoke(nameof(Init), value);
            _view.Init += value;
        }

        remove
        {
            Unsubscription?.Invoke(nameof(Init), value);
            _view.Init -= value;
        }
    }
    public event EventHandler Load
    {

        add
        {
            Subscription?.Invoke(nameof(Load), value);
            _view.Init += value;
        }

        remove
        {
            Unsubscription?.Invoke(nameof(Load), value);
            _view.Init -= value;
        }
    }

    public void DataBind()
    {
        _view.DataBind();
    }
}

J'ai passé un peu de temps sur cette question et la solution que j'utilise dans mon projet est la suivante:

Test unitaire:

// Arrange
TestedObject.Setup(x => x.OnEvent1());
TestedObject.Setup(x => x.OnEvent2());

// Act
TestedObject.Object.SubscribeEvents();
TestedObject.Raise(x => x.Event1 += null);
TestedObject.Raise(x => x.Event2 += null);

// Assert
TestedObject.Verify(x => x.OnEvent1(), Times.Once());
TestedObject.Verify(x => x.OnEvent2(), Times.Once());

Méthode testée:

this.Event1 += OnEvent1;
this.Event2 += OnEvent2;

Donc, vous devez d’abord vous moquer des méthodes avec lesquelles vous allez affecter les événements, après avoir appelé la méthode que vous voulez tester et enfin déclenché tous les événements abonnés. Si l'événement est réellement abonné, vous pouvez vérifier auprès de Moq si la méthode affectée est appelée.

GLHF!

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