在单元测试期间断言WF服务变量的值

时间:2012-03-12 18:40:07

标签: workflow-foundation workflow-foundation-4

我需要在工作流服务中声明变量的值。

我已经下载并使用CodePlex的Microsoft.Activities.UnitTesting框架来测试工作流服务端点,返回值和流逻辑 - 但我需要在调用端点后验证变量的值得到回应 - 这可能吗?

如果没有其他类型的解决方法可能有效涉及更改工作流本身以生成输出参数?因为在制作时我当然不需要一个。

谢谢!

更新2.A

目前使用存根方法而不是WCF方法来测试服务。

[TestMethod]
[DeploymentItem(@"TestService\Service1.xamlx")]
public void TestValueOfInteger1AfterStart()
{
    // inject the mocks into the service
    var xamlInjector = new XamlInjector("Service1.xamlx");
    xamlInjector.ReplaceAll(typeof(Receive), typeof(ReceiveStub));
    xamlInjector.ReplaceAll(typeof(SendReply), typeof(SendReplyStub));

    // setup the messages
    var stubExtension = new MessagingStubExtension();

    // enqueue a message for the receive activity using parameters content
    stubExtension.EnqueueReceive(XName.Get("{http://tempuri.org/}IService"), "Start", null);

    // setup the host
    var host = WorkflowInvokerTest.Create(xamlInjector.GetWorkflowService().Body);
    host.Extensions.Add(stubExtension);

    try
    {
        host.TestActivity();
        ...

更新2.B

因此,经过一些努力,我发现如果我使用存根,我可以通过反射来恢复上下文,而不是使用WCF端点进行单元测试。上面是存根单元测试代码的一个exerpt,下面是我用来获取刷新的ActivityContext的反射代码。但是,现在我在尝试获取变量的值时遇到以下错误。

有趣的是,您可以清楚地看到上下文所关联的活动是定义它的活动 - 糟糕的框架只是有点困惑。

Exception when trying to grab the variable value.

...
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;

// recover the WorkflowInstance
var proxy = stubExtension.GetType().GetProperty("InstanceProxy",
                                                bindingFlags).GetValue(stubExtension,
                                                                       bindingFlags,
                                                                       null,
                                                                       null,
                                                                       null) as WorkflowInstanceProxy;

// recover the WorkflowInstance
var fieldInfo = proxy.GetType().GetField("instance", bindingFlags);
var workflowInstance = fieldInfo.GetValue(proxy) as WorkflowApplication;

// recover the ActivityExecutor
fieldInfo = workflowInstance.GetType().BaseType.GetField("executor", bindingFlags);
dynamic activityExecutor = fieldInfo.GetValue(workflowInstance);

// recover the rootInstance
fieldInfo = activityExecutor.GetType().GetField("rootInstance", bindingFlags);
var rootInstance = fieldInfo.GetValue(activityExecutor) as ActivityInstance;

// recover the cachedResolutionContext
fieldInfo = activityExecutor.GetType().GetField("cachedResolutionContext", bindingFlags);
var cachedResolutionContext = fieldInfo.GetValue(activityExecutor) as ActivityContext;

MethodInfo methodInfo = cachedResolutionContext.GetType().GetMethod("Reinitialize", bindingFlags);
methodInfo.Invoke(cachedResolutionContext, bindingFlags, null, new object[]
                                                                   {
                                                                       rootInstance,
                                                                       activityExecutor
                                                                   }, null);

var val = (int)((Sequence)rootInstance.Activity).Variables.First(x => x.Name == "integer1").Get(cachedResolutionContext);
Assert.AreEqual(val, 1, "The integer value of integer1 is not correct.");

2 个答案:

答案 0 :(得分:1)

您可以使用AppFabric跟踪并监控变量。

然而,问题提出了另一个问题,即如果您已经在测试流逻辑和输出,为什么需要测试wf实例的内部状态?

答案 1 :(得分:0)

我开始使用这个工具来做我的对象断言:

http://comparenetobjects.codeplex.com/

它是开源的,并且很好地使用反射来断言复杂对象的值。