问题
In a Silverlight 5 application in Dynamics CRM 2011 I access the Organization Service of the CRM to query for entity Metadata. I wrote a service that takes an entity name and returns a list of all its fields.
How can I test this service method automatically? The main problem is how to obtain a reference to the organization service from a Silverlight app that does not run in the context of the CRM.
My Service method looks like this:
public IOrganizationService OrganizationService
{
get
{
if (_organizationService == null)
_organizationService = SilverlightUtility.GetSoapService();
return _organizationService;
}
set { _organizationService = value; }
}
public async Task<List<string>> GetAttributeNamesOfEntity(string entityName)
{
// build request
OrganizationRequest request = new OrganizationRequest
{
RequestName = "RetrieveEntity",
Parameters = new ParameterCollection
{
new XrmSoap.KeyValuePair<string, object>()
{
Key = "EntityFilters",
Value = EntityFilters.Attributes
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "RetrieveAsIfPublished",
Value = true
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "LogicalName",
Value = "avobase_tradeorder"
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "MetadataId",
Value = new Guid("00000000-0000-0000-0000-000000000000")
}
}
};
// fire request
IAsyncResult result = OrganizationService.BeginExecute(request, null, OrganizationService);
// wait for response
TaskFactory<OrganizationResponse> tf = new TaskFactory<OrganizationResponse>();
OrganizationResponse response = await tf.FromAsync(
OrganizationService.BeginExecute(request, null, null), iar => OrganizationService.EndExecute(result));
// parse response
EntityMetadata entities = (EntityMetadata)response["EntityMetadata"];
return entities.Attributes.Select(attr => attr.LogicalName).ToList();
}
Edit: I can create and execute unit tests with Resharper and AgUnit. Thus, the problem is not how to write a unit test in general.
回答1:
I have tweaked the GetSoapService from the standard Microsoft SDK to accept a fall back value. This means no codes changes are needed when debugging in visual studio and running in CRM. Anyway here it is
public static IOrganizationService GetSoapService(string FallbackValue = null)
{
Uri serviceUrl = new Uri(GetServerBaseUrl(FallbackValue)+ "/XRMServices/2011/Organization.svc/web");
BasicHttpBinding binding = new BasicHttpBinding(Uri.UriSchemeHttps == serviceUrl.Scheme
? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);
binding.MaxReceivedMessageSize = int.MaxValue;
binding.MaxBufferSize = int.MaxValue;
binding.SendTimeout = TimeSpan.FromMinutes(20);
IOrganizationService ser =new OrganizationServiceClient(binding, new EndpointAddress(serviceUrl));
return ser;
}
public static string GetServerBaseUrl(string FallbackValue = null)
{
try
{
string serverUrl = (string)GetContext().Invoke("getClientUrl");
//Remove the trailing forwards slash returned by CRM Online
//So that it is always consistent with CRM On Premises
if (serverUrl.EndsWith("/"))
{
serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
}
return serverUrl;
}
catch
{
//Try the old getServerUrl
try
{
string serverUrl = (string)GetContext().Invoke("getServerUrl");
//Remove the trailing forwards slash returned by CRM Online
//So that it is always consistent with CRM On Premises
if (serverUrl.EndsWith("/"))
{
serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
}
return serverUrl;
}
catch
{
return FallbackValue;
}
}
来源:https://stackoverflow.com/questions/19496623/how-to-unit-test-soap-service-access-from-crm-2011-silverlight-application