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); }
Filed under: Microsoft Dynamics CRM Tagged: Microsoft Dynamics CRM
