Test and mock (custom) organization messages with FakeXrmEasy in Dynamics 365 CRM

FakeXrmEasy supports many of the common CRM standard organization messages out of the box. With “supports” I mean that it not only exposes simple mock/fake/stub/whatever facilities for these messages — like f.e. intercepting executions thereof –, but rathermore FakeXrmEasy provides runnable implementations of them which behave much like the “real” CRM message pendant. Using these, we can test workflows, plugins and general client code which internally use the CRM organization service for executing organization messages or reacting to them without having to write any message processing logic by ourselves. As said … FakeXrmEasy supports many messages out of the box, but by far not all and in more or less similar behaviour.

FakeXrmEasy supports common messages like f.e. Create, Retrieve, RetrieveMultiple, Update and Delete and therefore provides kind of a “virtual” mini CRM system including things like an organization message processing pipeline which behaves similar to “real” CRM and wherein all organization messages are executed. Of course my comparison is very simplistic, but I hope you got the idea. 😉 

How to test and mock organization messages

However, there are also several messages which are not implemented (yet) by FakeXrmEasy and thus have to be mocked/stubbed/faked by our test code, depending on our testing scenario. FakeXrmEasy uses an extensible strategy pattern for registering message handlers and when determining which handler implementation to use for a given organization message.

Mocking any of the missing CRM standard messages or any of our custom message (like calling an Action) can be done in two different ways:

  1. Returning some predefined response data 
  2. Implement a full fledged request request handler 

To be more specific, using the following methods provided by class XrmFakedContext:

  • AddExecutionMock<T>(ServiceRequestExecution mock
    • Purpose: Register delegate function of type ServiceRequestExecution (which takes OrganizationRequest object as input and returns OrganizationResponse object as output) which returns some (predefined) response data for every message of type <T> whereas T is OrganizationRequest or a derivate of it. 
  • AddFakeMessageExecutor<T>(IFakeMessageExecutor executor)
    • Note: Generic method variant does also exist, where message name is passed as additional paramter to method → AddGenericFakeMessageExecutor(string message, IFakeMessageExecutor executor) 
    • Purpose: Register full fledged message executor implementation for messages of type <T> whereas T is OrganizationRequest or a derivate of it. This interface plays a central role in FakeXrmEasy since all standard organization messages which are supported out of the box, are implement as classes which implement IFakeMessageExecutor. These are organized using the chain of responsibility pattern, where a message in the message processing pipeline is handed over to every registered message executor instance until one is found that `CanExecute` it.

How to implement a custom message handler

Given we have a CRM process of type Action which is called “xy_GetEnergyProductDetailsBySapRateCode”. Now how should we for example test a workflow which internally calls this action or any custom CRM client code which calles this action? But now step by step. First we create two specialized messages classes which makes it easier for us to execute the message using organizationService.Execute(…):

Well, let’s assume we just want to return some predefined response inside our test code. We can do this like:



Summary

FakeXrmEasy is a very helpful and extensible testing solution for Dynamics CRM plugins, workflows and general SDK client code. It not only is around for a long time and has matured noticeably over time, it is also backed by a comprehensive test suite and does support CRM 2011 until latest version 9.x including all their specifics. While the official documentation may shed some light onto general questions for new users, they will leave the reader with more questions than he came. But that’s okay, because its open source and freely available on GitHub, so everybody can should dive into the internal FakeXrmEasy test suites and analyze how it’s implemented. It’s very insightful. When this is not enough or you want to get up and running asap, the awesome Jordi Montana offers training courses and also several premium support plans –> https://dynamicsvalue.com/

When any of the XRM/CRM standard organization messages is not already included out of the box, we can easily add support for them by ourselves by registering a message executor instance of a simple execution mock delegate.

Note: when we attempt to execute an orgnization message which is not supported (read: no message executer is registered for) FakeXrmEasy throws a very charming not implemented exception.

Processes and arguments of type “Picklist” ━ a dead end street

Yesterday, one of the few perfect fits for a combination of Dialog and Action Processes have crossed my mind while revising a business requirement. Being satisfied because having found an elegant solution wich furthermore consists of no code or indirections, I first designed the Action Process. The part which caused my today’s rumbling is the following:

First we defined an in-argument of type Picklist (=OptionSet) as required and 
then wanted to write it into an OptionSet field..

Problem 

Microsoft Dynamics 365 (online and on-premise) still does not allow Picklist arguments to be written into Picklist fields.

Solution (😉)

Come on, are you kidding me?? But the story doesn’t end here. I investigated on this issue and found out, that this restriction is imposed somewhere in the platform UI layer, because the underlying Workflow engine used internally by the CRM platform (Windows Workflow Foundation with references to product-specific assemblies) to handle is undoubtedly able to handle those argument types. I exported my Action in a temp solution and edited the XAML workflow definition file manually, so that the above Picklist argument is written into the target field “Business Partner Type”. With success. Oh, and by the way: manually editing declarative workflow processes from MSCRM is supported even for Online.

So again, being happy about having also fixed this issue, I went on by creating my Dialog Process which would have to be invoked by the actual user for choosing the business partner type along with some other parametrized inputs. Then, as last step I added an “Invoke Action” command … but wtf is this? The list of available Actions does not contain the one I just finished before!

After some cross-checks it turned out this behaviour is solely related to the fact that the Action said does contain an In-Argument of type Picklist. Nothing else.

Finishing Move

Action Processes with in-arguments of type “Picklist” cannot be invoked from other Processes. This dilletante limitation seems to be around (google for it) since 2013 and I would not bet a cent that it will be fixed anytime soon.