Утверждение значения служебной переменной WF во время модульного теста - PullRequest
3 голосов
/ 12 марта 2012

Мне нужно утвердить значение переменной в службе рабочего процесса.

Я уже скачал и использую платформу Microsoft.Activities.UnitTesting из CodePlex для проверки конечной точки службы рабочего процесса, возвращаемых значений и логики потока - но мне нужно проверить значение переменной после вызова конечной точки и получить ответ - это возможно?

Если это не так, есть ли другой тип обходного пути, который может сработать, что не включает в себя изменение самого рабочего процесса для получения выходного параметра? Потому что, когда я буду в производстве, он мне точно не понадобится.

Спасибо!

ОБНОВЛЕНИЕ 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 для модульного теста я мог бы восстановить контекст с помощью отражения, если бы использовал заглушки. Выше приведен фрагмент кода модульного тестирования заглушек, а ниже - код отражения, который я использую для получения обновленного 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 ]

1 голос
/ 03 апреля 2012

Вы можете использовать отслеживание AppFabric и контролировать переменную.

Однако возникает вопрос: если вы уже тестируете логику потока и выходные данные, зачем вам проверять внутреннее состояние экземпляра wf?

0 голосов
/ 21 марта 2012

Я начал использовать этот инструмент, чтобы делать утверждения объектов:

http://comparenetobjects.codeplex.com/

Это открытый исходный код, и он хорошо работает с использованием отражения для утверждения значений сложных объектов.

...