Testing SharePoint Workflows using TypeMock Isolator (Part 3)
Now I can test a basic workflow it soon becomes obvious that you could end up with many tests for a single workflow, as a workflow can have any number of criteria that could cause branching to occur. Maybe a sensible way to write the tests is using Fit/Fitness to provide the test cases in tabular form?
So to this end I have added a bit more code to my Typemock/Sharepoint test project (after installing the Fit libraries as detailed in my previous posts). I now have a single test that loads a set of test criteria from an HTML file (my previous posts discuss why I am using HTML files as opposed to the Fit Wiki).
1: [TestMethod]
2: public void WorkFlow1SwitchOnTitle_DataViaFitnesse_Success()
3: {
4: fit.Runner.FolderRunner runner = new fit.Runner.FolderRunner(new fit.Runner.ConsoleReporter());
5: var errorCount = runner.Run(new string[] {
6: "-i",@"WorkflowTestCases.htm", // the htm file that holds the test
7: "-a",@"TestProject.dll", //we have the fit facade in this assembly
8: "-o",@"results"}); // the directory the results are dumped into as HTML
9: // fit can fail silently giving no failures as no test are run, so check for exceptions
10: Assert.AreEqual(false, Regex.IsMatch(runner.Results, "^0.+?0.+?0.+?0.+?$"), "No tests appear to have been run");
11: // look for expected errors
12: Assert.AreEqual(0, errorCount, runner.Results);
13:
14: }
I then have an HTML file that contains the test cases (remember to make sure that this file is deployed to the output directory)
1: <HTML><HEAD>
2: <body>
3: <table border="1" cellspacing="0">
4: <tr><td>import</td>
5: </tr>
6: <tr><td>TestProject</td>
7: </tr>
8: </table>
9:
10: <table border="1" cellspacing="0">
11: <tr><td colspan="2">Workflow Fit Tests</td>
12: </tr>
13: <tr><td>Upload Document With Title </td>
14: <td>Document Approved?</td>
15: </tr>
16: <tr><td>ABC</td>
17: <td>True</td>
18: </tr>
19: <tr><td>XYZ</td>
20: <td>False</td>
21: </tr>
22: <tr><td>abc</td>
23: <td>True</td>
24: </tr>
25: </table>
26:
27: </body>
28: </html>
Finally we need to create the facade class that wrapper the workflow function for Fit to call. In this sample I just popped the class in the test project for simplicity. Notice it is this facade class that contains all the Typemock bits, also that I make use of the helper class I created in my previous post to actually run the workflow.
1: using System;
2: using TypeMock.ArrangeActAssert;
3: using Microsoft.SharePoint.Workflow;
4:
5: namespace TestProject
6: {
7: public class WorkflowFitTests : fit.ColumnFixture
8: {
9: public string UploadDocumentWithTitle;
10:
11: public bool DocumentApproved()
12: {
13:
14: var fakeProperties = Isolate.Fake.Instance<SPWorkflowActivationProperties>();
15: var fakeItem = fakeProperties.Item;
16: Isolate.WhenCalled(() => fakeItem.Title).WillReturn(this.UploadDocumentWithTitle);
17:
18: // Act
19: TypemockWorkflowTests.WorkflowRunner(typeof(SharePointWorkflow.Workflow1), fakeProperties);
20:
21: // Assert, if a document is approved must call the following two line
22: try
23: {
24: Isolate.Verify.WasCalledWithExactArguments(() => fakeItem.Update());
25: Isolate.Verify.WasCalledWithExactArguments(() => fakeItem["Approved"] = "True");
26: return true; // we called all the updates expected
27: }
28: catch (TypeMock.VerifyException)
29: {
30: // it did not call something expected, check if it was just the not approved path
31: Isolate.Verify.WasNotCalled(() => fakeItem.Update());
32: return false;
33: }
34:
35: }
36: }
37: }
I am currently working on a sample of this testing technique, that does a bit more than a simple branch on if test, I will post a set of sample code when I am done.
Read the complete post at http://blogs.blackmarble.co.uk/blogs/rfennell/archive/2009/04/07/testing-sharepoint-workflows-using-typemock-isolator-part-3.aspx