Dynamics CRM 2011 Unit Test Part 4: Microsoft Fakes with CrmOrganizationServiceContext
Dynamics CRM 2011 Unit Test Part 1: Introduction and Series Contents
The complete sample code using Microsoft Fakes can be downloaded from MSDN sample gallery: Dynamics CRM unit test using Microsoft Fakes
If you know IOrganizationService API and underlining messages, there is also an indirect approach to unit test CrmOrganizationServiceContext, which is to mock the underlining IOrganizationService. That is discussed in another post (Part 7: Microsoft Fakes with CrmOrganizationServiceContext through IOrganizationService).
CrmOrganizationServiceContext
CrmOrganizationServiceContext is SDK Extensions contained in Microsoft.Xrm.Client assembly. CrmOrganizationServiceContext allows the entity objects produced by the data context to participate in the WCF Data Services framework. CrmOrganizationServiceContext provide methods from various OrganizationRequest, which means a method based implementation of the message API. These methods are defined as extension methods, to use these methods we have to include the Microsoft.Xrm.Client.Messages namespace.
For more information on CrmOrganizationServiceContext, see Developer Extensions Context Object Model
Microsoft Fakes does not support CrmOrganizationServiceContext, if we try to set up a run time delegate, we will receive ShimNotSupported exception. So we can go the traditional way to extract interface and provide a wrap type around CrmOrganizationServiceContext and implement that interface.
Most of the methods contained within SDK extension are OrganizationServiceContext extension methods. These methods are defined in Microsoft.Xrm.Client.Messages.OrganizationServiceContextExtensions and Microsoft.Xrm.Client.OrganizationServiceContextExtensions. And I have created one Interface and a wrapper Class.
https://gist.github.com/3180585
https://gist.github.com/3180591
namespace CrmOrganizationServiceContextExtensions
{
public interface ICrmOrganizationServiceContext
{
/*
* Microsoft.Xrm.Client.Messages.OrganizationServiceContextExtensions
*/
/*
* Microsoft.Xrm.Client.CrmOrganizationServiceContext
*/
}
}
namespace CrmOrganizationServiceContextExtensions
{
public class CrmContext : CrmOrganizationServiceContext, ICrmOrganizationServiceContext
{
public CrmContext() : base() { }
public CrmContext(string contextName) : base(contextName) { }
public CrmContext(CrmConnection connection) : base(connection) { }
public CrmContext(IOrganizationService service) : base(service) { }
private Microsoft.Xrm.Sdk.Client.OrganizationServiceContext _context;
private Microsoft.Xrm.Sdk.Client.OrganizationServiceContext Context
{
get
{
if (_context == null)
{
_context = this as Microsoft.Xrm.Sdk.Client.OrganizationServiceContext;
}
return _context;
}
}
/*
* Microsoft.Xrm.Client.Messages.OrganizationServiceContextExtensions
*/
/*
* Microsoft.Xrm.Client.OrganizationServiceContextExtensions
*/
}
}
We can start using the Interface and wrapper Class in our code.
Suppose we have the following code under test
public class CrmContextMethods
{
private ICrmOrganizationServiceContext _crmContext;
public CrmContextMethods(ICrmOrganizationServiceContext crmContext)
{
_crmContext = crmContext;
}
public string RetrieveVersion()
{
var version = _crmContext.RetrieveVersion();
return version;
}
public Guid CreateAccount(string name)
{
var entity = new Entity("account")
{
Attributes = new Microsoft.Xrm.Sdk.AttributeCollection
{
{ "name", name }
}
};
var id = _crmContext.Create(entity);
return id;
}
}
The unit test code code could be
[TestClass]
public class CrmContextMethodsTest
{
[TestMethod]
public void CreateAccountTest()
{
//
// Arrange
//
string accountName = "abcabcabc";
Guid actual;
Guid expected = Guid.NewGuid();
int callCount = 0;
Entity entity = null;
var context = new CrmOrganizationServiceContextExtensions.Fakes.StubICrmOrganizationServiceContext();
context.CreateEntity = e =>
{
callCount++;
entity = e;
return expected;
};
CrmContextMethods target = new CrmContextMethods(context);
//
// Act
//
actual = target.CreateAccount(accountName);
//
// Assert
//
Assert.AreEqual(callCount, 1); // verify OrganizationServiceContext.Create is called once
Assert.IsNotNull(entity); // verify OrganizationServiceContext.Create is called with not null object
Assert.AreEqual(entity.LogicalName, "account"); // verify OrganizationServiceContext.Create is called with entity with proper entity name
Assert.AreEqual(entity.GetAttributeValue<string>("name"), accountName); // verify OrganizationServiceContext.Create is called with entity with proper value set on name attribute
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void RetrieveVersionTest()
{
//
// Arrange
//
string actual;
string expected = "5.0.9690.2243";
int callCount = 0;
var context = new CrmOrganizationServiceContextExtensions.Fakes.StubICrmOrganizationServiceContext();
context.RetrieveVersion = () =>
{
callCount++;
return expected;
};
CrmContextMethods target = new CrmContextMethods(context);
//
// Act
//
actual = target.RetrieveVersion();
//
// Assert
//
Assert.AreEqual(callCount, 1); // verify OrganizationServiceContext.RetrieveVersion is called once
Assert.AreEqual(expected, actual);
}
}
This was originally posted here.

Like
Report
*This post is locked for comments