views:

182

answers:

2

Problem: during execution, instances of classes that derives from System.Workflow.ComponentModel.Activity is serialized by the workflow engine. I'd like to unit test these types in order to ensure that they can be serialized. As of now, these exceptions only show up in production.

Non-working solution:

public class UnitTestActivity : Activity
{}

[Test]
public void ShouldBeSerializable()
{
   var activity = new UnitTestActivity();

   activity.Clone(); // throws exception here
}

The test above yields the following exception "System.InvalidOperationException : This is an invalid design time operation. You can only perform the operation at runtime."

I've also tried the activity.Save(...) method which then throws the same exception. The code I used is:

public static void SerializeToFile( Activity activity )
{
   using (var fileStream = new FileStream( GetFilePath(), FileMode.Create ))
   {
      IFormatter formatter = new BinaryFormatter { SurrogateSelector = ActivitySurrogateSelector.Default };

      activity.Save( fileStream, formatter );
   }
}
A: 

I think you would need to spin up an instance with a persistence service in the host, and try and persist it.

(The custom workflow type is itself not serialised when persisting the workflow, but just its state.)

Richard
A: 

I implemented a workaround solution that loops through all the fields of every Activity heir and tries to serialize it. The NUnit test looks like so (helpers omitted):

[Test, TestCaseSource( "GetActivities" )]
public void ShouldBeSerializable( Activity activity )
{
    var fieldInfos = activity.GetType().GetFields( BindingFlags.Public | BindingFlags.NonPublic 
                                                   | BindingFlags.Instance | BindingFlags.Static );

    fieldInfos.Where( fieldInfo => fieldInfo.Name != "parent" )
              .ForEach( fieldInfo =>
                            {
                                var fieldValue = fieldInfo.GetValue( activity );

                                if ( fieldValue != null )
                                {
                                    Serializer.Clone( fieldValue ); // no assert, throws exception if not serializable
                                }
                            } );
}
Martin R-L