One of the nice things in Dynamics CRM 2011 and in a similar way in CRM4.0 with Sdk 13 is the ability to query CRM data using LINQ.
The centerpiece for this feature is the ServiceContext. This allows you to do a query using LINQ.
Now when it comes to unit testing the code the ServiceContext is a pain.
What I wanted to do is to be able to define the data, the ServiceContext queries on, while not being connected to CRM.
So, I needed a way to redirect the ServiceContext to a List.
Searching through documentation I found the overridable
protected IQueryable<TEntity> CreateQuery<TEntity>(IQueryProvider provider, string entityLogicalName)
method. This is a factory method that than uses the query provider to query the data.
Now I extend the ServiceContext class and override the CreateQuery method:
public class TestServiceContext : ServiceContext
{
public ICollection<Entity> Data { get; private set; }
public TestServiceContext(IOrganizationService service, ICollection<Entity> data) : base(service)
{
Data = data;
}
[SuppressMessage("Microsoft.Design", "CA1004", Justification = "Design cannot be changed, as method signature is provided by Xrm OrganizationServiceContext")]
protected override IQueryable<TEntity> CreateQuery<TEntity>(IQueryProvider provider, string entityLogicalName)
{
return Data.OfType<TEntity>().Where(data => { var entityData = data as Entity;
if (entityData != null)
return entityData.LogicalName == entityLogicalName;
else
return false;}).AsQueryable();
}
}
Basically there can be two cases that have to be reckoned with:
- Queries created using ServiceContext.CreateQuery<Account>()
- Queries created using ServiceContext.CreateQuery(Account.LogicalName)
That’s why we reduce the returned data set to those OfType<TEntity> and then query it down to those entities having the specified logical name.
Using this implementation of TestServiceContext now actually queries on the Data collection.
Now you should have a Factory that creates your ServiceContext in your code, using a Mocking library you can then return the TestServiceContext when calling the factory.
I will show a use case and a test in the next couple of days.
No comments:
Post a Comment