Dynamics CRM 2011 Unit Test Part 14: Rhino Mocks with CRM plugin

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

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

Unit test CRM plugin is straightforward as well, it is just a bit tedious. IPlugin.Execute only accept one parameter which is IServiceProvider. Through IServiceProvider we can retrieve at least 3 interface and we need to set up 5 interface, which will be IOrganizationService, IPluginExecutionContext, ITracingService, IOrganizationServiceFactory and IServiceProvider.

Suppose we have a sample Dynamics CRM plugin, which is called after a contact is created within Dynamics CRM, if the parent customer is set to an account, the number of employees attribute of that account will be increased by one.

Code Under Test


public class Plugin : IPlugin
 {
 private string _unsecure, _secure;

/// <summary>
 /// Alias of the image registered for the snapshot of the
 /// primary entity's attributes after the core platform operation executes.
 /// The image contains the following attributes:
 /// parentcustomerid
 ///
 /// Note: Only synchronous post-event and asynchronous registered plug-ins
 /// have PostEntityImages populated.
 /// </summary>
 private readonly string postImageAlias = "PostCreateImage";

public Plugin(string unsecure, string secure)
 {
 _unsecure = unsecure;
 _secure = secure;
 }

public void Execute(IServiceProvider serviceProvider)
 {
 // Obtain the execution context service from the service provider.
 var pluginExecutionContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

if (pluginExecutionContext.Stage == 40 && pluginExecutionContext.MessageName == "Create" && pluginExecutionContext.PrimaryEntityName == "contact")
 {
 // Obtain the tracing service from the service provider.
 var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

// Obtain the Organization Service factory service from the service provider
 IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

// Use the factory to generate the Organization Service.
 var organizationService = factory.CreateOrganizationService(pluginExecutionContext.UserId);

Entity postImageEntity = (pluginExecutionContext.PostEntityImages != null && pluginExecutionContext.PostEntityImages.Contains(this.postImageAlias)) ? pluginExecutionContext.PostEntityImages[this.postImageAlias] : null;

// when a contact is created with parent account, increase number of employees for that account
 if (postImageEntity != null && postImageEntity.Contains("parentcustomerid"))
 {
 EntityReference parentCustomer = postImageEntity.GetAttributeValue<EntityReference>("parentcustomerid");

if (parentCustomer != null && parentCustomer.LogicalName.ToLowerInvariant() == "account")
 {
 tracingService.Trace("Parent account id: {0}.", parentCustomer.Id);

Entity parentAccount = organizationService.Retrieve("account", parentCustomer.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet("numberofemployees"));

int numberOfEmployees = 0;
 if (parentAccount.Contains("numberofemployees"))
 {
 numberOfEmployees = parentAccount.GetAttributeValue<int>("numberofemployees");
 }

parentAccount["numberofemployees"] = numberOfEmployees + 1;

organizationService.Update(parentAccount);
 }
 }
 }
 }
 }

Unit Test

[TestMethod()]
 public void ExecuteTest()
 {
 //
 // Arrange
 //
 string unsecure = "unsecure";
 string secure = "secure";
 Plugin target = new Plugin(unsecure, secure);

var accountId = Guid.NewGuid();
 var previousNumber = 3;
 var expected = 4;
 var actual = 0;

// IOrganizationService
 var service = MockRepository.GenerateStub<IOrganizationService>();
 service.Stub(x => x.Retrieve(null, Guid.Empty, null)).IgnoreArguments().Return(
 new Microsoft.Xrm.Sdk.Entity("account")
 {
 Id = accountId,
 Attributes = { { "numberofemployees", previousNumber } }
 });

service.Stub(x => x.Update(null)).IgnoreArguments().Do((Action<Entity>)delegate(Entity entity)
 {
 actual = entity.GetAttributeValue<int>("numberofemployees");
 });

// IPluginExecutionContext
 var pluginExecutionContext = MockRepository.GenerateStub<IPluginExecutionContext>();
 pluginExecutionContext.Stub(x => x.Stage).Return(40);
 pluginExecutionContext.Stub(x => x.MessageName).Return("Create");
 pluginExecutionContext.Stub(x => x.PrimaryEntityName).Return("contact");
 pluginExecutionContext.Stub(x => x.PostEntityImages).Return(new EntityImageCollection
 {
 { "PostCreateImage", new Microsoft.Xrm.Sdk.Entity("contact")
 {
 Attributes = { { "parentcustomerid", new EntityReference("account", accountId) } }
 }
 }
 });

// ITracingService
 var tracingService = MockRepository.GenerateStub<ITracingService>();
 tracingService.Stub(x => x.Trace(null, null)).IgnoreArguments().Do((Action<string, object[]>)delegate(string f, object[] o)
 {
 Debug.WriteLine(f, o);
 });

// IOrganizationServiceFactory
 var factory = MockRepository.GenerateStub<IOrganizationServiceFactory>();
 factory.Stub(x => x.CreateOrganizationService(null)).IgnoreArguments().Return(service);

// IServiceProvider
 var serviceProvider = MockRepository.GenerateStub<IServiceProvider>();
 serviceProvider.Stub(x => x.GetService(null)).IgnoreArguments().Do((Func<Type, object>)delegate(Type t)
 {
 if (t == typeof(IPluginExecutionContext))
 {
 return pluginExecutionContext;
 }
 else if (t == typeof(ITracingService))
 {
 return tracingService;
 }
 else if (t == typeof(IOrganizationServiceFactory))
 {
 return factory;
 }

return null;
 });

//
 // Act
 //
 target.Execute(serviceProvider);

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

Advertisements

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