Dynamics CRM 2011 Unit Test Part 5: Microsoft Fakes with LINQ query through IOrganizationService

Dynamics CRM 2011 Unit Test Part 1: Introduction and Series Contents

The complete sample code using Microsoft Fakes can be downloaded from MSDN sample gallery: Dynamics CRM unit test using Microsoft Fakes

In a previous post (Part 2: Microsoft Fakes with LINQ query), I have describe how to use run time redirect delegate feature of Microsoft Fakes to unit test LINQ to CRM query. I consider this a direct approach since you do not need to understand the IOrganizationService API and you do not need to know all the underlining messages. If you know IOrganizationService API and underlining messages, there is also an indirect approach to unit test LINQ to CRM query, which is to mock the underlining IOrganizationService.

To use LINQ to query CRM data, we need to use OrganizationServiceContext or a deriving class such as CrmOrganizationServiceContext which is SDK Extensions contained in Microsoft.Xrm.Client assembly, or a deriving class created by the CrmSvcUtil tool. The OrganizationServiceContext class contains an underlying LINQ query provider that translates LINQ queries from Microsoft Visual C# or Microsoft Visual Basic .NET syntax into the query API used by Microsoft Dynamics CRM.

We need to provide an instance of IOrganizationService to construct OrganizationServiceContext, OrganizationServiceContext is going to translate LINQ to CRM query into RetrieveMultipleRequest and execute that OrganizationRequest by calling IOrganizationService.Execute. If we mock IOrganizationService properly, we can isolate LINQ to CRM query unit test.

Code under test


public class LINQToCRM2
 {
 private OrganizationServiceContext _context;

public LINQToCRM2(IOrganizationService service)
 {
 _context = new OrganizationServiceContext(service);
 }

public IEnumerable<Entity> RetrieveAccountsByName(string name)
 {
 var query = from account in _context.CreateQuery("account")
 where account.GetAttributeValue<string>("name") == name
 select account;

var accountList = new List<Entity>();

foreach (var entity in query)
 {
 accountList.Add(entity);
 }

//We can simply call query.ToList()
 //foreach loop here is to demonstrate item Enumeration

return accountList;
 }

public Entity RetrieveAccountsById(Guid id)
 {
 var query = from account in _context.CreateQuery("account")
 where account.GetAttributeValue<Guid>("accountid") == id
 select account;

var accountEntity = query.FirstOrDefault();

return accountEntity;
 }
 }

Unit Test


[TestClass]
 public class LINQToCRM2Test
 {
 [TestMethod]
 public void RetrieveAccountsByNameTest()
 {
 //
 // Arrange
 //
 var entity1 = new Microsoft.Xrm.Sdk.Entity("account");
 entity1.Id = Guid.NewGuid();
 entity1["name"] = "abcabcabc";

var entity2 = new Microsoft.Xrm.Sdk.Entity("account");
 entity2.Id = Guid.NewGuid();
 entity2["name"] = "123123123";

var entity3 = new Microsoft.Xrm.Sdk.Entity("account");
 entity3.Id = Guid.NewGuid();
 entity3["name"] = "a1b2c3a1b2c3";

var service = new Microsoft.Xrm.Sdk.Fakes.StubIOrganizationService();

service.ExecuteOrganizationRequest = r =>
 {
 List<Entity> entities = new List<Entity>
 {
 entity1, entity2
 };

var response = new RetrieveMultipleResponse
 {
 Results = new ParameterCollection
 {
 { "EntityCollection", new EntityCollection(entities) }
 }
 };

return response;
 };

string accountName = "abcabcabc";
 IEnumerable<Microsoft.Xrm.Sdk.Entity> actual;
 LINQToCRM2 target = new LINQToCRM2(service);

//
 // Act
 //
 actual = target.RetrieveAccountsByName(accountName);

//
 // Assert
 //
 Assert.AreEqual(2, actual.Count());
 Assert.AreEqual(entity1, actual.ElementAt(0));
 Assert.AreEqual(entity2, actual.ElementAt(1));
 }

[TestMethod]
 public void RetrieveAccountsByIdTest()
 {
 //
 // Arrange
 //
 Guid id = Guid.NewGuid();

Microsoft.Xrm.Sdk.Entity expected = new Microsoft.Xrm.Sdk.Entity { Id = id };

var service = new Microsoft.Xrm.Sdk.Fakes.StubIOrganizationService();

service.ExecuteOrganizationRequest = r =>
 {
 List<Entity> entities = new List<Entity>
 {
 expected
 };

var response = new RetrieveMultipleResponse
 {
 Results = new ParameterCollection
 {
 { "EntityCollection", new EntityCollection(entities) }
 }
 };

return response;
 };

Microsoft.Xrm.Sdk.Entity actual;
 LINQToCRM2 target = new LINQToCRM2(service);

//
 // Act
 //
 actual = target.RetrieveAccountsById(id);

//
 // Assert
 //
 Assert.AreEqual(expected, actual);
 }
 }

Advertisements

3 comments on “Dynamics CRM 2011 Unit Test Part 5: Microsoft Fakes with LINQ query through IOrganizationService

  1. Pingback: Dynamics CRM 2011 Unit Test Part 2: Microsoft Fakes with LINQ query | Zhongchen Zhou's Blog

  2. Pingback: Dynamics CRM 2011 Unit Test Part 1: Introduction and Series Contents | Zhongchen Zhou's Blog

  3. Pingback: Information to Get started with Unit Testing with Microsoft Fakes and CRM – Hosk's Dynamic CRM Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s