2012-03-12 74 views
3

我需要在工作流服务中声明变量的值。在单元测试中断言WF服务变量的值

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

如果不是有一些其他类型的解决方法可能工作涉及改变工作流本身产生一个输出参数?因为在生产中我当然不需要一个。

谢谢!

UPDATE 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(); 
     ... 

UPDATE 2.B

于是,经过一番更多的努力我发现,而不是使用WCF端点的单元测试,我可以通过反射恢复方面,如果我用存根。上面是stubs单元测试代码的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."); 
+0

我将在大约一个小时内为此付出代价 - 我希望像@ RonJacobs这样的人能够帮助我! – 2012-03-14 17:32:16

回答

1

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

但是,这个问题引发了进一步的问题,如果您已经在测试流程逻辑和输出,为什么您需要测试wf实例的内部状态?

+0

这正是我们最终做的 - 谢谢! – 2012-04-03 00:03:43

相关问题