前几部分内容,学习到如何输出一个字符串到控制台,既不可以接受输入参数,也不能提供输出参数,与大部分的应用程序的需求不太一致。同时,现在的形式也不太容易进行测试。
我们将修改SayHello activity,使之可以接收输入参数,也可以输出参数,而不是将消息输出到控制台,这样SayHello就可以被应用到其它的大型业务逻辑中。SayHello需要达到的功能类似于以下的代码:
private static string SayHello(string name )
{
return "Hello " + name + " from Workflow 4";
}
任务1 – 添加新的单元测试项目到当前的解决方案
- 首先添加单元测试项目,以便验证工作流行为。在Solution Explorer 右键点击HelloWorkflow 解决方案,选择Add / New Project 并选择项目设置选项:
- 已安装的模板: Visual C# --> Test
- 模板:Test Project
- 名称:HelloWorkflow.Tests
- 添加引用到HelloWorkflow.Tests项目
- 右键点击HelloWorkflow.Tests项目,选择Add Reference
- 在Projects 页,选择HelloWorkflow 项目以添加项目引用
- 在.NET 页,添加System.Activities 库
- 右键点击UnitTest1.cs ,重新名称为SayHelloFixture.cs ,在提示是否对类名重新命名的时候选择Yes
任务 2 – 创建测试方法
在实际实现功能之前,先创建一个测试方法,这是TDD的主要做法。测试驱动式开发(Test Driven Development,TDD),是一种非常好的编程模式,根据业务逻辑,先设定好测试方法,然后再编码使其通过测试。对比实现逻辑前后的测试结果,从failed到passed来达到业务逻辑的实施。
- 添加以下命名空间到SayHelloFixture.cs
using System.Activities;
using HelloWorkflow;
- 创建一个测试方法,使你的工作流能够以设想的方式进行。打开SayHelloFixture.cs 并将TestMethod1 方法修改为ShouldReturnGreetingWithName
- 以下代码复制到此方法中
[TestMethod ]
public void ShouldReturnGreetingWithName ()
{
IDictionary <string, object> output;
output = WorkflowInvoker.Invoke(
new SayHello()
{
UserName = "Test"
});
Assert.AreEqual ("Hello Test from Workflow 4", output["Greeting "]);
}
这里有2个知识点:
- 如何传递输入参数给工作流activity
- 通过创建activiy实例时,利用.NET3.5/4初始化对象的简化代码,对公共属性(Property)直接赋值
- 或者传递Dictionary<string, object>实例,将匹配好的数据作为参数给Invoke调用
output = WorkflowInvoker.Invoke(
new SayHello(),
new Dictionary <string, object>()
{
{ "UserName", "Test" }
});
- 如何获取activity的输出参数
- 输出参数是IDictionary<string, object>类型,输出变量的名称作为字典的键值
任务 3 – 编译程序看看测试结果
现在只是写好测试方法,并未在activity中实现,编译项目看看编译状态如何。
- 按CTRL+SHIFT+B 编译程序,应该显示编译错误
- HelloWorldflow.SayHello 并不存在 UserName 的定义
- 打开SayHello.xaml ,在设计器的下方,有Variables,Arguments 和Imports,分别对应节点内变量、输入输出参数和引用。点击Arguments并添加参数
- 参数1:UserName ,输入,字符串
- 参数2:Greeting ,输出,字符串
- 在WF中,参数代表了流入或流出activity的数据
- 按CTRL+SHIFT+B编译,错误应该没有了
任务 4 – 运行测试,可预想测试不会通过
要记住,TDD的做法是,编写好测试方法后,在没有真正实施功能之前,测试一定是不会被通过的,否则只能说明测试方法存在bug以至于测试成功(功能都没实现,怎么可能成功呢?!)
- 按CTRL+R,T 运行当前范围内的单元测试,测试会被运行,但会失败,因为工作流节点现在并没有输出任何内容到Greeting输出参数
任务 5 – 实现功能,使测试通过
- 在设计器打开SayHello.xaml
- 输出文本到控制台永远不能使测试通过,因此需要删除此节点,右键点击WriteLine 节点并选择Delete
- 通过Assign 节点赋值给Greeting
- 从工具栏的Primitives组中选择Assign 节点并拖动到设计界面
- 设置Assign节点的To 属性为Greeting
- 输入Assign节点的Value 属性
- 可以通过设计界面直接输入
- 或者通过属性窗口的右侧... 按钮打开表达式编辑器(Expression Editor )窗口,输入更长的表达式
- 属性Value的值设置为:"Hello " & UserName & " from Workflow 4"
- 注意,在WF表达式中,永远都只能使用VB表达式,所以如果要换行,必须使用下划线 _
- 按CTRL +SHIFT +B 编译,应该没有错误
验证 – 测试可以成功
- 通过Test 菜单的Windows/Test View,打开Test View 窗口
- 选择ShouldReturnGreetingWithName 测试并点击Run Selection 按钮
- 在Test Results 窗口验证测试是否Passed