I have been using Microsoft Fakes for CRM unit testing which was good however recently came across xrm unit testing framework developed by Wael Hamze and Ramon Tebar which makes life much easier when comes to unit testing.
You can write fake quires and use them where needed.
In below sample we have a situation where we have two queries in our plugin and want to get some data from CRM and then update an other record on the basis of that.
public class PreAccountCreate:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service for use in debugging sandboxed plug-ins.
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext localContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(localContext.UserId);
Entity entity = null;
if (localContext.InputParameters.Contains("Target") && localContext.InputParameters["Target"] is Entity)
entity = ((Entity)localContext.InputParameters["Target"]);
else
throw new InvalidPluginExecutionException("Entity record was not found as Target in Plugin Context");
QueryByAttribute query = new QueryByAttribute()
{
ColumnSet = new ColumnSet("new_value"),
EntityName = "new_configuration",
Attributes = { "new_name" },
Values = { "AutoNumberPrefix" }
};
EntityCollection entities = service.RetrieveMultiple(query);
//***test
QueryExpression _qe1 = new QueryExpression("opportunity")
{
Distinct = false,
ColumnSet = new ColumnSet ( "name" ),
Criteria =
{
Filters =
{
new FilterExpression{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("customerid", ConditionOperator.Equal, Guid.NewGuid())
}
}
}
}
};
var opportunitiesResult = service.RetrieveMultiple(_qe1);
}
}
In above plugin we are using QueryByAttribute and QueryExpression to fetch some data. We can fake this in our test rather than depending on real data.
In our Test Class> SetUpPlugin we can filter and find out about the QueryExpression and return data back accordingly if we have more than one query
protected override IPlugin SetupPlugin()
{
//First thing let the framework know the context of plugin.
base.SetPluginEvent("account", "Create", Xrm.Framework.Test.Unit.SdkMessageProcessingStepImage.PreOperation);
//Next as you know the plug-in retrieves a configuration value from CRM. So in your setup you need to fake that call and retrieves a static value instead.
base.OrganizationServiceStub.RetrieveMultipleQueryBase = (query) =>
{
EntityCollection entities = new EntityCollection();
if (query is QueryByAttribute)
{
if (((Microsoft.Xrm.Sdk.Query.QueryByAttribute)(query)).EntityName == "new_configuration")
{
Entity config = new Entity("new_configuration");
config["new_value"] = _prefix;
entities.Entities.Add(config);
}
}
if(query is QueryExpression)
{
var _q = (QueryExpression)query;
if (_q.EntityName == "opportunity")
{
Entity xyz = new Entity("oppurtunity");
xyz["name"] = "Hello oppurtunity";
entities.Entities.Add(xyz);
}
}
return entities;
};
// set target
base.SetTarget(new Entity("account"));
// finally return instance of plugin
IPlugin plugin = new PreAccountCreate();
return plugin;
}
Similarly we can differentiate between multiple queries where needed.