One thing I’ve been doing a lot of work with recently is ADX Studio CRM Metal for Microsoft Dynamics CRM. If you don’t know already, CRM Metal builds a linq-to-crm type data context model for you, using the Dynamics CRM web services. It’s a really great piece of work, and I can’t imagine extending CRM without it.
One problem is unit testing code that uses the crm data context layer. Just to ‘set out my stall’, I’m not really interested in unit testing that the data context layer works, but I do want to test the layer above it. Up until recently my approach to this has been to extract an IDataContext interface from the actual auto-generated data context layer. I can then dependency inject this interface into my object under test, and mock against it (using Moq of course)!
Where this method falls down is when you want to use the associated entities – what I mean is when I have an instance of the contact entity (for example), I might want to get contact.addresses. This causes a problem with the my method, as in my tests I’m generally returning faked objects from my mocked data context calls, and calling the associated ‘addresses’ property causes stuff to happen which results in an error (generally because my fake is not attached to an actual data context). The associated entity is a powerful feature of linq and crm data context, and I up until recently I’ve had to omit using it as I had no way to unit test around it.
To get around this, I tried mocking / stubbing various objects and interfaces with no luck until I got some excellent help from John Leung from ADX Studio. Not only did this enable my unit testing, it also gave me a better understanding of how the data context works. I’ll explain this with the following 2 examples:
Simple Retrieval of Entity
First example is to mock out a simple Linq query for an entity, and its response:
1. Create a fake person object:
Guid contactId = Guid.NewGuid(); Contact c = new Contact(); c.ContactID = personId;
2. Create a fake BusinessEntityCollection with the fake person in it (note the use of
ICrmEntity to use ToDynamicEntity
BusinessEntityCollection contacts = new BusinessEntityCollection() { BusinessEntities = new List { ((ICrmEntity)p).ToDynamicEntity() } };
3. Create a mock of IOrganizationService, and stub out a RetrieveMultiple call. Note that the argument is “It.IsAny…”, but this could easily be more specific.
<pre>Mock orgSvc = new Mock(); orgSvc.Setup(x => x.RetrieveMultiple(It.IsAny())).Returns(contacts);
4. Create your data context, passing in the mock IOrganisationService as an argument
var dataContext = new XrmDataContext("Xrm", () => orgSvc.Object);
5. This should enable the following call to return the fake person object
var contact = dataContext.Contacts.Where(x => x.ContactID == contactId).First();
More Complex Retrieval of Related Entity
This example builds on the last example to show how you can fake out calls to retrieve related entities (note the step numbers, as they indicate whereabouts they fit in with the above example.
3.1. Create a fake address
Address address = new Address(); address.AddressName = "Test";
3.2. Create a fake RetrieveMultipleResponse object, with the address as part of it:
<pre>var response = new RetrieveMultipleResponse { BusinessEntityCollection = new BusinessEntityCollection { BusinessEntities = new List { ((ICrmEntity)address).ToDynamicEntity() } } };
3.3. Stub out an Execute call on the mock IOrganizationService. Note the use of It.IsAny() – this could easily be made more specific.
<pre>orgSvc.Setup(x => x.Execute(It.IsAny())).Returns(response);
5. Complete steps 4 & 5 as per previous example, then the following should work
<pre>var address = contact.Addresses.First();</pre>
So, thats about it! I hope someone finds this useful and if not, well at least I’ve got it down on paper!
Matt
The post Unit Testing ADXStudio CrmMetal Data Context appeared first on Codenutz - all about how to make an app.