When you finished your Dynamics CRM Plugin you need to write a Unit test to achieve 100% code coverage. Writing unit tests can be difficult, time-consuming, and slow when you can't isolate the classes you want to test from the rest of the system. Here are some steps you need to follow and cover your plugin code using Unit test methods.
Here in this blog, I have explained how to write unit test method for different functionality, data types and events like Retrieve, Retrieve Multiple, PreImage data, Post Image data, Entity, EntityReference, Option set, TargetEntity data, etc.
Step 1
Add Fakes references to your MS project
The Fakes Assemblies will automatically be created in your project.
Now you can start writing your Unit test method code.
Always remember Unit test for the plugin is passing hardcoded value only. The plugin does not connect with the CRM database while writing the Unit test methods.
Step 2
Use Fakes libraries in your Unittest.cs file
Now the below code is for every test method will be same. It contains the declaration, Initialization of the IPlugin interface.
-
-
-
- private OrganizationResponse response = new CreateResponse();
-
-
-
-
- private static StubIServiceProvider ServiceProvider { get; set; }
-
-
-
-
- private static StubIPluginExecutionContext PluginExecutionContext { get; set; }
-
-
-
-
- private static StubIOrganizationService OrganizationService { get; set; }
-
-
-
-
- private Entity TestEntity { get; set; }
-
-
-
-
-
- [ClassInitialize]
- public static void ClassInit(TestContext textContext)
- {
- var context = new StubIPluginExecutionContext();
- var tracingService = new StubITracingService();
- var orgFactory = new StubIOrganizationServiceFactory();
- ServiceProvider = new StubIServiceProvider();
- OrganizationService = new StubIOrganizationService();
- PluginExecutionContext = context;
-
-
- ServiceProvider.GetServiceType = (type) =>
- {
- if (type == typeof(IPluginExecutionContext))
- {
- return context;
- }
- else if (type == typeof(IOrganizationServiceFactory))
- {
- return orgFactory;
- }
- else if (type == typeof(ITracingService))
- {
- return tracingService;
- }
- else if (type == typeof(IOrganizationService))
- {
- return OrganizationService;
- }
-
- return null;
- };
-
-
- orgFactory.CreateOrganizationServiceNullableOfGuid = (userId) => OrganizationService;
-
-
- tracingService.TraceStringObjectArray = (message, args) => Debug.WriteLine(message, args);
- }
-
-
-
-
- [TestInitialize]
- public void TestInit()
- {
-
- var inputParameters = new ParameterCollection();
- PluginExecutionContext.InputParametersGet = () => inputParameters;
- this.TestEntity = new Entity();
- inputParameters.Add(new KeyValuePair<string, object>("Target", this.TestEntity));
- }
-
-
-
-
- [TestCleanup]
- public void TestCleanup()
- {
- this.TestEntity = null;
- }
Step 3
Write your Unit test methods
- [TestMethod]
- public void UnitTestMethod()
- {
-
- ParameterCollection parameter;
-
-
- PluginExecutionContext.InputParametersGet = () =>
- {
- parameter = new ParameterCollection
- {
- ["Target"] = new Entity("account", Guid.Parse("e910c8ae-4c9d-e911-a98f-002248005d8"))
- {
- }
- };
- return parameter;
- };
-
- PluginExecutionContext.PostEntityImagesGet = () =>
- {
-
- Entity contactEntity = new Entity("contact", Guid.NewGuid());
-
-
- EntityImageCollection parameterImage = new EntityImageCollection();
-
-
- EntityReference entityReference = new EntityReference
- {
- Id = Guid.NewGuid(),
- LogicalName = "opportunity"
- };
-
- contactEntity["opportunityid"] = entityReference;
-
-
- contactEntity["advertise"] = new OptionSetValue(3);
-
-
- contactEntity["starttime"] = DateTime.Now;
-
-
- parameterImage["PostImage"] = contactEntity;
-
- return parameterImage;
- };
-
- PluginExecutionContext.PreEntityImagesGet = () =>
- {
-
- EntityImageCollection parameterImage = new EntityImageCollection();
- parameterImage["PreImage"] = new Entity();
- return parameterImage;
- };
-
-
- OrganizationService.RetrieveStringGuidColumnSet = (entityName, id, columns) =>
- {
- var entity = new Entity(entityName)
- {
- Id = id
- };
- entity.Attributes["date"] = DateTime.Now.AddHours(2);
- entity.Attributes["dateTime"] = DateTime.Now.AddHours(4);
- return entity;
- };
-
-
- OrganizationService.RetrieveMultipleQueryBase = (req) =>
- {
- EntityCollection ec = null;
- if (req is FetchExpression)
- {
- var fe = req as FetchExpression;
- if (fe.Query.Contains("msdyn_timegroupdetail"))
- {
- ec = new EntityCollection();
- ec.Entities.Add(new Entity()
- {
- Attributes = new AttributeCollection()
- {
- { "msdyn_starttime", DateTime.Now.AddHours(2)},
- { "msdyn_endtime", DateTime.Now.AddHours(3)},
- }
- });
- }
- }
- if (req is QueryExpression)
- {
- ec = new EntityCollection();
- ec.Entities.Add(new Entity()
- {
- Attributes = new AttributeCollection()
- {
- { "timezonecode", 85},
- }
- });
- }
- return ec;
- };
- PluginExecutionContext.StageGet = () => 40;
- PluginExecutionContext.MessageNameGet = () => "Update";
- PluginExecutionContext.PrimaryEntityNameGet = () => "account";
- UnittestPlugin unitTestPlugin = new UnittestPlugin();
- unitTestPlugin.Execute(ServiceProvider);
- }
Using the above code you can easily cover your code coverage for your code.
Somewhere in the code, we needed a plugin exception for code coverages. Using the below code you can cover the IPluginExecutionException, FaultException, Exception for the exception handling process in the Unit test.
- [TestMethod, ExpectedException(typeof(InvalidPluginExecutionException))]
- public void PluginException()
- {
-
- ParameterCollection parameter;
-
-
- PluginExecutionContext.InputParametersGet = () =>
- {
- parameter = new ParameterCollection
- {
- ["Target"] = new Entity("account", new Guid("ed33f83c-9ed3-e911-a813-000d3a6d652"))
- {
- Attributes = {
-
- }
- }
- };
- return parameter;
- };
- }
For Fault Exception put null values or make cast error,
- [TestMethod, ExpectedException(typeof(InvalidCastException))]
- public void LoggedInUserDoesNotHaveSysAdminRole()
- {
-
-
- PluginExecutionContext.PreEntityImagesGet = () =>
- {
- EntityImageCollection preImage = new EntityImageCollection
- {
- ["PreImage"] = new Entity("account")
- {
- Attributes = {
- { "accountcategorycode", "value" }
- }
- }
- };
- return preImage;
- };
- }
I hope this article will solve your problem with writing a Unit test using Fakes.
Keep learning new things.....