Unit Testing Workflow Activities

I've been kicking around the best approach for unit testing a custom activity for Windows Workflow. I haven't found an approach I'm comfortable with as yet.

Here is a simple, contrived custom activity.

using System;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;

[assembly:
XmlnsDefinition("http://odetocode.com/wf/activities",
                          
"OdeToCode.WF.Activities")]
namespace OdeToCode.WF.Activities
{
   
public class CreateMessageActivity : Activity
   {

    
private string _recipient;
    
public string Recipient
    {
      
set { _recipient = value; }
    }

    
private string _message;
    
public string Message
    {
      
get { return _message; }
    }
   
    
protected override ActivityExecutionStatus
      Execute(
ActivityExecutionContext executionContext)
    {

      _message =
String.Format("Message to {0}", _recipient);
      
return ActivityExecutionStatus.Closed;
    }
   }
}

It's tempting to create a unit test that instantiates the activity and calls Execute directly, but most activities are not this simple. The ActivityExecutionContext class is sealed, and mocking out all the scheduling services, queues, and other dependencies inside is a task for Sisyphus.

Another approach is to test the activity using the WF runtime. A little bit of hacking produces:

[TestFixture]
public class CreateMessageActivityTests
{
  [
TestFixtureSetUp]
  
public void StartWfRuntime()
  {
    _runtime =
new WorkflowRuntime();
    
    
// use manual scheduler for synchronous execution
    _scheduler = new ManualWorkflowSchedulerService();
    _runtime.AddService(_scheduler);

    
// type provider needed to resolve custom activity in XAML
    TypeProvider typeProvider = new TypeProvider(_runtime);
    typeProvider.AddAssembly(
Assembly.Load("ActivityLibrary2"));
    _runtime.AddService(typeProvider);

    _runtime.WorkflowCompleted +=
        
new EventHandler<WorkflowCompletedEventArgs>
          (_runtime_WorkflowCompleted);
    _runtime.WorkflowTerminated +=
        
new EventHandler<WorkflowTerminatedEventArgs>
          (_runtime_WorkflowTerminated);
  }

  [
TestFixtureTearDown]
  
public void ShutdownWfRuntime()
  {
    _runtime.StopRuntime();
    _runtime.Dispose();
  }

  [
SetUp]
  
public void SetupTest()
  {
    _exception =
null;
    _outputs =
null;
  }

  
void _runtime_WorkflowTerminated(
      
object sender,
      
WorkflowTerminatedEventArgs e
    )
  {
    _exception = e.Exception;
  }

  
void _runtime_WorkflowCompleted(
      
object sender,
      
WorkflowCompletedEventArgs e
    )
  {
    _outputs = e.OutputParameters;
  }

  
WorkflowRuntime _runtime = null;
  
ManualWorkflowSchedulerService _scheduler;
  
Dictionary<string, object> _outputs;
  
Exception _exception;

  
// create custom activity as the root of a workflow
  string _xaml =
    
@"<otc:CreateMessageActivity
         xmlns:otc=""http://odetocode.com/wf/activities"">
      </otc:CreateMessageActivity>"
;
}

This is a lot of code, and I haven't even written a test yet. Unit testing a custom activity is an indirect process because the workflow runtime tries to shield a workflow instance from the callous hands of the outside world.

[Test]
public void CreatesMessageForScott()
{
  
XmlReader reader = XmlReader.Create(
                      
new StringReader(_xaml)
                     );

  
Dictionary<string, object> parameters;
  parameters =
new Dictionary<string, object>();
  parameters.Add(
"Recipient", "Scott");

  
WorkflowInstance instance;
  instance = _runtime.CreateWorkflow(reader,
null, parameters);
  instance.Start();
  _scheduler.RunWorkflow(instance.InstanceId);

  
Assert.IsNull(_exception, "Workflow threw an exception");
  
Assert.AreEqual(_outputs.Count, 1);

  
// .. and so on

}

I'm feeding a XAML definition of a workflow to the runtime in an attempt to simplify the process and isolate the activity. Still, this code is still far too lengthy and complex to maintain in a unit test. My plan is to create a project of utility classes to simplify the code even further, but I'm still apprehensive.

Anyone else unit testing activities or workflows?

posted on Wednesday, August 02, 2006 10:30 PM by scott

Comments

Thursday, August 03, 2006 8:30 PM by Christopher Steen

# Link Listing - August 3, 2006


TRULY
Understanding ViewState [Via: InfinitiesLoop ]
How-Do-I
Video - Using the Atlas...
Thursday, August 31, 2006 1:20 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:22 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:23 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:26 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:27 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:28 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:29 AM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:52 AM by Community Blogs

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 1:52 AM by ASP.NET Team Blogs

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Thursday, August 31, 2006 6:02 AM by while(availableTime>0) {

# WF: Windows Workflow Foundation

Yeah, I know that&#180;s a strange acronym and that it should be WWF, but what would it be of WWF , then?...
Sunday, September 03, 2006 11:59 PM by ScottGu's Blog

# Windows Workflow Foundation

Workflow is one of the new core capabilities (along with WPF aka Avalon and WCF aka Indigo) being added
Monday, October 16, 2006 1:17 PM by David

# re: Unit Testing Workflow Activities

It seems to me that the best practice for unit testing an activity stems from the best practice for developing activities. That is, treat the activity just as a wrapper around a component. Instead of having to test the activity, you can just test the component and validate it.
Tuesday, July 31, 2007 2:01 PM by Damir Dobric Posts

# WF - Unit Testing: How to create Activity Type from XOML?

Typically, one workflow can be started with the code similar to following one: WorkflowInstance instance;
Tuesday, July 31, 2007 2:07 PM by Damir Dobric Posts

# WF - Unit Testing: How to create Activity Type from XOML?

Typically, one workflow can be started with the code similar to following one: WorkflowInstance instance;
Wednesday, August 01, 2007 3:41 PM by Damir Dobric Posts

# WF - Unit Testing: How to create Activity Type from XOML?

Typically, one workflow can be started with the code similar to following one: WorkflowInstance instance;
Sunday, January 20, 2008 8:53 PM by K. Scott Allen

# A Few Interesting Windows Workflow Links

Igor emailed me for my thoughts about his SMTP server built with Windows Workflow. A link for the source...
Sunday, January 20, 2008 9:00 PM by BusinessRx Reading List

# A Few Interesting Windows Workflow Links

Igor emailed me for my thoughts about his SMTP server built with Windows Workflow . A link for the source
Monday, February 04, 2008 10:13 AM by Community Blogs

# A Few Interesting Windows Workflow Links

Igor emailed me for my thoughts about his SMTP server built with Windows Workflow . A link for the source
Sunday, April 13, 2008 1:26 AM by Yoot

# Unit Testing custom Workflow Activities

Unit Testing custom Workflow Activities
Friday, May 09, 2008 8:35 AM by Yoot

# Unit Testing custom Workflow Activities

Unit Testing custom Workflow Activities