我们编写一个测试用例,如下:
[Test]
public void SearchArtifactOfCompTest()
{
MockViewListDescPict view;
view=测试用的View;
view.ComponentId = "265f1e5d-2c75-4368-9a3a-5da5d82270c5";
ListDescPictPresenter presenter = new ListDescPictPresenter(view);
view.AttachPresenter(presenter);
view执行click button的动作;
Assert.IsTrue(((IList
}
先解释一下这个测试用例的意思。首先创建一个测试用的view,然后用它初始化presenter,当view执行一个点击button的动作之后,presenter会去响应这个操作,将取出的数据传给view的列表控件显示,如果成功则列表控件的数据源中应该有6条纪录。
现在运行这个测试用例肯定是失败的,因为标记为红色的代码都是没有实现的伪代码。为了让测试通过,我们尝试实现红色标记处所要求的功能。
- view=测试用的View
这里实际上是要求一个满足契约IViewListDescPict的view,我们虽然没有真正的view,但是我们可以编写一个模拟的view(mock view)——可以联想在模块化测试时编写桩(stub)模块的情形。MockViewListDescPict是一个模拟的view,它实现了IViewListDescPict接口。那么一个问题就解决了:
view=new MockViewListDescPict(); - view执行click button的动作
上一篇中讲到presenter是采用观察者模式,它监听button的事件。既然只要事件,那我们只要模拟一个事件就行了,并不需要真的用一个button。搞清楚button的click是产生一个普通的event,那我们定义一个:
public EventHandler searchArtsOfComp_Event;
事件的触发很简单:searchArtsOfComp_Event.Invoke(null, null);
我们把触发的代码放在一个方法中,以便在测试的时候模拟:
public void MockClickSearchButton()
{
searchArtsOfComp_Event.Invoke(null, null);
}
接下来我们要让presenter注册对该事件的监听,以便在invoke触发事件的时候能被presenter捕捉到,我们把这一步放在AttachPresener中进行:
public void AttachPresenter(ListDescPictPresenter presenter)
{
this.presenter = presenter;
searchArtsOfComp_Event = presenter.SearchPictOfComp_EventHandler;
}
其中presenter.SearchPictOfComp_EventHandler是一个指向方法SearchPictOfComp(见应用篇)的委托。
到此,第二个问题也解决了:
view.MockClickSearchButton();
public object descPictList;
public void SetPictListDataSource(IList
{
descPictList = pictList;
}
当我们模拟了button的click事件之后,presenter根据它的内部逻辑会去调用view的
总结一下对presenter的测试,一共有三点:
1、不需要真的view,可以使用类似Mock Object这样的技术模拟一个view,只要模拟的对象满足IView的契约即可。
2、如果要从view中获得用户的数据,比如要从textbox中取得用户输入的查询条件,又或者需要将处理的结果数据发回view显示,比如将一个list的集合发送到ListBox显示,这两类问题我们都可以使用对字段或者属性的存取操作来模拟。因为我们不关心显示,只要数据正确传送即可,将显示的任务交给view,可是使得presenter的功能独立于显示层。
3、对于像用户点击button或者选择chechbox这样的交互行为,我们不需要真的用控件来测试。.net允许我们手动触发事件,比如EventHandler.Invoke(),因此我们可以用手动触发事件的方式来模拟用户的交互行为。
没有评论:
发表评论