Michael Riva
Michael Riva

Reputation: 541

Testing event listener

In my code:

public class StudentPresenter
{
    IView myview;
    Repository myrepo;
    public StudentPresenter(IView vw, Data.Repository rep)
    {
        this.myview = vw;
        this.myrepo = rep;
        this.myview.ButonClick += myview_ButonClick;
    }

    public void myview_ButonClick()
    {
        var d = this.myrepo.GetById(int.Parse(myview.GivenId));
        this.myview.GetStudent(d);
    }
}

I want to test GetStudent method will call, So I tried

[Test]
public void ctor_whenviewbuttonclick_callsviewButtonClickevent()
{
    var mock = Substitute.For<IView>();
    var stub=Substitute.For<Repository>();
    Student st = new Student();
    stub.When(p => p.GetById(Arg.Any<int>())).Do(x => st=new Student());

    StudentPresenter sp = new StudentPresenter(mock, stub);

    mock.ButonClick += Raise.Event<Action>();

    mock.Received().GetStudent(st);      
}

But test broken: Says:

Application.UnitTests.Form1Tests.ctor_whenviewbuttonclick_callsviewButtonClickevent: NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching: GetStudent(Student) Actually received no matching calls.

What I m doing wrong here?

Upvotes: 2

Views: 938

Answers (1)

David Tchepak
David Tchepak

Reputation: 10484

This error is likely caused by Repository.GetById() not being virtual. The introduction on the Creating a substitute page of the documentation has a paragraph on things to look out for when substituting for classes.

Once that is sorted there are a few other tweaks to the test required to get it to run. I've commented those parts, and done some minor renames to make it a bit easier for me to follow.

[Test]
public void ctor_whenviewbuttonclick_callsviewButtonClickevent()
{
    var view = Substitute.For<IView>();
    var repo = Substitute.For<Repository>();
    //Stub out GivenId
    view.GivenId.Returns("42");
    Student st = new Student();
    //Make GetById return a specific Student for the expected ID
    repo.GetById(42).Returns(x => st);

    StudentPresenter sp = new StudentPresenter(view, repo);

    view.ButonClick += Raise.Event<Action>();

    view.Received().GetStudent(st);
}

The first change is to stub out GivenId, as the presenter requires that to be a string that is parseable as an integer. The second is to make GetById return the expected student (the When..do syntax in your original example reassigns the st variable. It doesn't set a return value).

Hope this helps.

Upvotes: 3

Related Questions