Despite unit tests aren’t something new for most of us that’s not always the case inside the Dynamics CRM world. 🙁
In my experience, 1 out of 5 CRM developers write unit tests to test their code, actually, some of them build a console app to help them test their functionalities and there are even ones that just test their code after publishing into CRM, directly via the web interface. 😮
There might be several reasons why usually devs don’t write unit tests. Sometimes the project is too small, the number of customizations is minimal, the customers will not gonna like to pay the extra time needed to write tests, a legacy code may seem impossible to test, test plugins and workflows are not a trivial task, your team is not writing test, etc.
Despite all those reasons not to write them, the fact of having your code fully tested may help you sleep better at night. – literally, the chance of you receive a call from your client in the middle of the night is way less if you have tests for your code.
I could quote the benefits of having your code fully tested here but that’s not the target for today’s post, the purpose here is to encourage you to start writing them by showing a practical real code example of how you can start testing your CRM Plugins right now.
Keep in mind the following user story:
Whenever a new contact is created in CRM, if the record has an account related with it, the name of the contact record should be a concatenation of the account number and the contact name, if the record doesn’t have an account related an exception should be thrown.
The following code is the simpler we can go to achieve our requirement and keep the example didactical:
Pretty straightforward right? The first thing that we have to bear in mind when thinking in write unit tests is: We don’t want to access external services, perform SDK calls or call any other code that is not related with the method that we want to test.
Why? Simple, we should only test our code! The CRM SDK methods aren’t our code! Why should we test someone else code if we just want to test our plugin?
Ok, with that in mind we can start…
Wait… Our plugin does one SDK call to achieve our requirement if we don’t want to do SDK calls how can we test it?
There are different approaches to solve this issue. Maybe the disclosed one is Dependency Injection (DI).
Using DI, we could inject the dependencies that our plugin has (IServiceProvider) and we could define “fake” instances of those classes wherein instead of performing the expected operation we could just skip everything and return the result that we expect.
The most common strategies to implement DI is through injection by constructor or injection by setters, but we need to be careful with this kind of approaches as CRM Developers.
In both strategies, the dependencies are stored into class members and since CRM instantiate one instance of each plugin running concurrently you might end up with dependencies from the plugin execution 1 into the plugin execution 2.
As an alternative, we could use a technique called “Extract & Override” described in Art of Unit Testing – By the way, if you didn’t read this book yet you should.
“Extract & Override is a very powerful technique because it lets you deal directly with replacing the dependency without going down the rabbit hole at all (changing dependencies deep inside the call stack). That makes it very quick and clean to perform, almost to the point where it corrupts your good sense of object oriented aesthetics, leading you to code that might even have less interfaces but more virtual methods.” (Art of Unit Testing, Roy Osherove)
Although this technique is not complex to implement, after extract and override the dependencies we would still need to create mocks and/or stubs to our tests, and since this post is our Unit Test 101 we rather do something easy than something not complex, right?
How nice would it be if we could create an in-memory version of CRM, just with the data that we need to run our tests, that we didn’t need to worry about mocks, stubs, DI or any other thing unrelated with our code?
Ladies and gentlemen, I introduce you Fake XRM Easy, this library is defined by the author as:
The testing framework for Dynamics CRM and Dynamics 365 which runs on an In-Memory context and deals with mocks or fakes for you.
Wait!? That’s exactly what we need.
The library is opensource, the documentation is good and the website has even animations to guide us step by step through the samples.
Enough talking, what about the test for our plugin? Show me the code:
The only few things that we needed to do were:
- Download the Fake Xrm Easy lib – Which you can easily do via Nuget and Referencing in our test project.
- Create our CRM context and initialize with the data that we want.
- Execute the plugin and make the necessaries asserts.
If you made it until here I’m sorry but you don’t have more excuses not to write unit tests.