测试事件监听器

时间:2014-05-01 12:43:52

标签: c# nunit nsubstitute

在我的代码中:

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

我想测试GetStudent方法会调用,所以我试过

[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);      
}

但测试破了:说:

  

Application.UnitTests.Form1Tests.ctor_whenviewbuttonclick_callsviewButtonClickevent:   NSubstitute.Exceptions.ReceivedCallsException:预计会收到一个   呼叫匹配:GetStudent(学生)实际上没有收到匹配   呼叫。

我在这做错了什么?

1 个答案:

答案 0 :(得分:3)

此错误可能是Repository.GetById()不是virtual造成的。文档Creating a substitute页面上的介绍中有一段关于替换类时要注意的事项。

一旦对其进行了排序,还需要进行一些其他调整才能使其运行。我对这些部分进行了评论,并进行了一些小的重命名,以便让我更容易理解。

[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);
}

第一个更改是删除GivenId,因为演示者要求它是一个可解析为整数的字符串。第二个是让GetById返回预期的学生(原始示例中的When..do语法重新分配st变量。它不会设置返回值。)

希望这有帮助。