Microsoft Fakes and Plugin


Just sharing the helper class we use for writing Unit Test for Plugin using Microsoft Fakes

Sample Code for Plugin

</pre>
public class PluginClass: IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Everytime a lead record is created
// Create a corresponding contact record

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];

IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)
serviceProvider.GetService(typeof(IOrganizationServiceFactory));

IOrganizationService orgService = serviceFactory.CreateOrganizationService(context.UserId);

if (entity.LogicalName == "lead")
{
Entity contactEntity = new Entity("contact");
contactEntity.Attributes["lastname"] = entity.Attributes["subject"];
orgService.Create(contactEntity);
}
}
}
}

Sample Code for Unit Test Class

</pre>
[TestClass]
public class UnitTest1
{
[TestMethod]
public void UnitTestMethod()
{
var serviceProvider = new StubIServiceProvider();
var pluginContext = new StubIPluginExecutionContext();
var organizationService = new StubIOrganizationService();

// Mole the basic Plugin objects
Helper.FakePluginVariables(serviceProvider, pluginContext, organizationService, 40, "Create");

// set the mole of entity
var entityAttributes = new Dictionary<string, object>();

entityAttributes.Add("subject", "Test Subject");
Entity leadEntity = Helper.FakeEntity("lead", entityAttributes, pluginContext);

// set the entity in the parameter collection
var parameterAttributes = new Dictionary<string, object>();
parameterAttributes.Add("Target", leadEntity);
Helper.FakePluginInputParameters(pluginContext, parameterAttributes);

organizationService.CreateEntity = (p1) => { return Guid.NewGuid(); };

var postCreateLead = new Class1();
postCreateLead.Execute(serviceProvider);
}
}

Helper class

</pre>
/// <summary>
/// Helper class for Fakes
/// </summary>
public static class Helper
{
/// <summary>
/// Fakes the plugin variables.
/// </summary>
/// <param name="serviceProvider">The service provider.</param>
/// <param name="pluginContext">The plugin context.</param>
/// <param name="organizationService">The organization service.</param>
/// <param name="stageNumber">The stage number.</param>
/// <param name="messageName">Name of the message.</param>
public static void FakePluginVariables(
StubIServiceProvider serviceProvider,
StubIPluginExecutionContext pluginContext,
StubIOrganizationService organizationService,
int stageNumber,
string messageName)
{
var serviceFactory = new StubIOrganizationServiceFactory();
var tracingService = new StubITracingService();
if (serviceProvider != null)
{
serviceProvider.GetServiceType = type =>
{
if (type == typeof(IPluginExecutionContext))
{
return pluginContext;
}
else if (type == typeof(ITracingService))
{
return tracingService;
}
else if (type == typeof(IOrganizationServiceFactory))
{
return serviceFactory;
}

return null;
};
}

pluginContext.DepthGet = () => 1;
pluginContext.UserIdGet = () => new Guid();
pluginContext.MessageNameGet = () => messageName;
pluginContext.StageGet = () => stageNumber;
pluginContext.InitiatingUserIdGet = () => new Guid();
pluginContext.CorrelationIdGet = () => new Guid();
pluginContext.PrimaryEntityIdGet = Guid.NewGuid;
serviceFactory.CreateOrganizationServiceNullableOfGuid = t1 => organizationService;
tracingService.TraceStringObjectArray = Trace;
}

/// <summary>
/// Sets the Fakes for the Entity
/// </summary>
/// <param name="entityName">The LogicalName of the entity</param>
/// <param name="attributeValues">The attributes of the entity</param>
/// <param name="context">Object of type SIPluginExecutionContext</param>
/// <returns>Object of type Entity</returns>
public static Entity FakeEntity(string entityName, Dictionary<string, object> attributeValues, StubIPluginExecutionContext context)
{
var entity = new Entity(entityName);
entity.Attributes = new AttributeCollection();

if (attributeValues != null)
{
foreach (string key in attributeValues.Keys)
{
entity.Attributes.Add(key, attributeValues[key]);
}
}

if (context != null)
{
context.PrimaryEntityNameGet = () => entityName;
}

entity.Id = Guid.NewGuid();

return entity;
}

/// <summary>
/// Fakes the PluginContext.InputParameters
/// </summary>
/// <param name="context">the mole of the IPluginExecutionContext</param>
/// <param name="inputParameterCollection">Object of type System.Dictionary</param>
public static void FakePluginInputParameters(StubIPluginExecutionContext context, Dictionary<string, object> inputParameterCollection)
{
if (inputParameterCollection != null)
{
var parameterCollection = new ParameterCollection();
foreach (var key in inputParameterCollection.Keys)
{
parameterCollection.Add(key, inputParameterCollection[key]);
}

if (context != null)
{
context.InputParametersGet = () => parameterCollection;
}
}
}

/// <summary>
/// Detour method for the CRM Trace method
/// </summary>
/// <param name="content">the message to be traced</param>
/// <param name="value">Object of type object []</param>
public static void Trace(string content, params object[] value)
{
}
}

 

// Update 
   organizationService.UpdateEntity = (p) =>
            {
            };

// Execute
  organizationService.ExecuteOrganizationRequest = orgReq =>
                {                  
                    return new OrganizationResponse();
                };

// Retrieve
 organizationService.RetrieveStringGuidColumnSet = (p1, p2, p3) =>
            {
                Entity entity = null;
                if (p1 == entity1.EntityLogicalName)
                {
                    entity = new Entity(entity1.EntityLogicalName);
                    entity.Id = Guid.NewGuid();
                    entity.Attributes["new_category"] = new OptionSetValue(12345);
                    entity.FormattedValues["new_category"] = "home";                   
                }
                else if (p1 == entity2.EntityLogicalName)
                {
                    entity = new Entity(entity2.EntityLogicalName);
                    entity.Id = Guid.NewGuid();
                    entity.Attributes["new_moneyattr"] = new Money(100.0M);                    
                }
                return entity;
            };  
			
//RetrieveMultiple
  organizationService.RetrieveMultipleQueryBase = delegate(QueryBase query)
            {
                var collection = new EntityCollection();
                Entity entity;
                if (query is FetchExpression)
                {
                    entity = new Entity(entity.EntityLogicalName);
                    entity.Attributes = new AttributeCollection();
                    entity.Attributes.Add("attr", "value");                
                    collection.Entities.Add(entity);
                }
                return collection;
            };
			
// PreImage
  pluginContext.PreEntityImagesGet = () =>
            {
                EntityImageCollection entityImgColl = new EntityImageCollection();
                Entity preImageEntity = new Entity(enitity1.EntityLogicalName);         
                preImageEntity.Attributes.Add("new_id", new EntityReference(entity2.EntityLogicalName, Guid.NewGuid()));
                preImageEntity.Attributes.Add("new_bool", false);
                KeyValuePair<string, Entity> kvp = new KeyValuePair<string, Entity>("PreImageAI", preImageEntity);
                entityImgColl.Add(kvp);
                return entityImgColl;
            };
			

			

 

Hope it helps

Cleared MB2-701: Extending Microsoft Dynamics CRM 2013.


Hi,

Yesterday I cleared the Extending exam.

It had 48 questions with 700 as passing score.

I had referred the official training material of CRM 2011 as the training material for CRM 2013 are not released yet. Apart from that I had gone through different articles and videos to prepare for it.

There were very few questions that were specific to CRM 2013. Mostly they were around new methods added in Client SDK.

For someone who has a good hands-on experience in development in CRM 2011, passing this exam would not be that difficult.

Bye.

Retrieve OptionSet Label using SDK.Metadata.RertrieveAttribute method in JavaScript (CRM 2011)


Hi,

Recently we were working on an HTML Web Resource which was using oData to fetch information regarding a particular entity which had multiple optionset fields in it.

As we know using oData we can get the value of the optionset field but not the label. While searching for the best possible way to get the label in Jscript came to know about the sdk.metadata.js sample code in SDK (sdk\samplecode\js\soapforjscript\soapforjscript\scripts)

It has RetrieveAttribute method in it which can be used to get the attribute metadata

We had an optionset attribute named Language in it, this is how we fetched all the label and the value for that field


var languageArray = [];

// this.RetrieveAttribute = function (EntityLogicalName, AttributeLogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack, passThroughObject
 SDK.Metadata.RetrieveAttribute("new_lawyer", "new_primary_language", null, true, function (result) {

for (var i = 0; i < result.OptionSet.Options.length; i++) {
 languageArray[result.OptionSet.Options[i].Value] = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
 }
 },
 function (error) {
 alert("error");
 }
 );

Hope it helps !

Cleared MB2-703: Microsoft Dynamics CRM 2013 Customization and Configuration Exam.


Finally took and cleared my first CRM 2013 exam i.e. Customization and Configuration today.

It had total 48 questions in it with passing score of 700.

As expected the main focus area were

  • Access Teams
  • Business Process Flows
  • Business Rules
  • Quick Create forms.
  • New Controls

So anyone planning to take this exam should focus around these new features added in CRM 2013.

Bye.

How to – Get OptionSet Label using FormattedValues property of Entity in Plugin in CRM


The easiest way to get the Label for the option set in plugin is using the FormattedValues property of the Entity.

The Post Create plugin on Contact record getting the label for the address type field.


if (context.InputParameters.Contains(“Target”) && 
context.InputParameters[“Target”] is Entity){

// Obtain the target entity from the input parmameters. 

Entity entity = (Entity) context.InputParameters[“Target”];

if(entity.Contains(“address1_addresstypecode”)){

string addressTypeCodeLabel = entity.FormattedValues[“address1_addresstypecode”];

entity.Attributes[“address1_city”] = addressTypeCodeLabel;

service.Update(entity);}

}

http://community.dynamics.com/crm/b/crmmitchmilam/archive/2013/04/18/crm-sdk-nugget-entity-formattedvalues-property.aspx

Hope it helps.

Advertisements

Using SOAP and OData endpoint of CRM 2013 online in Windows Store App


Connecting to CRM 2013 Online SOAP and OData endpoint through Windows 8 App.