I’ve been toying with a poor man’s solution to dependency injection/mocking. The goal is to test business logic in isolation without worrying about external dependencies.
I know Studio Pro can do this natively, but I’m not on Pro yet and I know there are others in the same boat.
Curious to hear any feedback…Does this make sense? Is there a better way? What have you done/seen?
Technique
The technique is basically this:
- When you have a dependency that’s hard to test, encapsulate it in a pair of workflows.
- Workflow 1: A mock
- Workflow 2: The real implementation
- Next, in the workflow that needs this dependency:
- Add an argument.
- I name it in_DependencyFilename_MyDependency. For example, in_DependencyFilename_GetEmails.
- The argument’s default value is the filename of the mock.
- Add an “Invoke Workflow File” activity.
- The filename you pass the activity is not a hardcoded string but rather your in_DependencyFilename_MyDependency argument.
- Add an argument.
- In the workflow that calls the dependency-calling workflow, set in_DependencyFilename_MyDependency to the filename of the real implementation.
Now when you’re debugging, the mock is called by default. In production, the real implementation is called instead.
Example
- You’re processing Outlook messages.
- You need to get unread emails, mark them read, and extract attachments.
With/Without Dependency Injection
- Without: You add a Get Outlook Mail Messages activity to your workflow. Any dev who works on this project now needs an Outlook account to test with. That makes it harder to test the business logic for that flow. If you interact with a lot of third-party services, managing those dependencies can become cumbersome.
- With: You put Get Outlook Mail Messages inside a separate workflow. Your main workflow calls that workflow or its corresponding mock, depending on the filename argument passed in (injected). The mock reads saved Outlook message files from the filesystem. Now the business logic can be tested in isolation.
Steps for Mocking
- Create a workflow named GetEmails.
- Move Get Outlook Mail Messages into that workflow.
- Have the workflow return the emails via an output argument, out_Emails.
- Create a folder named TestEmails in your project folder.
- Save some Outlook messages to it.
- Create a workflow named GetEmailsMock.
- Have it load all emails in the TestEmails folder.
- Have it return the loaded emails via an output argument, out_Emails.
- Create a workflow named ExtractAttachments.
- Create an argument named in_DependencyFilename_GetEmails.
- Direction: In
- Type: String
- Default value: “GetEmailsMock.xaml”
- Add an Invoke Workflow File activity.
- Filename: in_DependencyFilename_GetEmails
- Add an output argument, out_Emails, of the same type as the one in GetEmails/GetEmailsMock.
- Create an argument named in_DependencyFilename_GetEmails.
- In your main workflow:
- Add an Invoke Workflow File activity.
- Set the filename to “ExtractAttachments.xaml”.
When you debug ExtractAttachments, the mock will be called. When you run the whole project, the real workflow will be called.