简体   繁体   中英

How to refactor method to replace OrganizationServiceProxy with IOrganizationService

I'm attempting to refactor my code so that I can unit test using fakexrmeasy.

As part of the suggested refactor mentioned here , I've attempted to pass IOrganizationService into all of my classes and methods. However, some of my classes use variables and methods that IOrganizationService doesn't have, such as Timeout. I'm trying to find a way to refactor to use IOrganizationService without losing functionality.

This is how it exists before refactoring.

class testClass () {

    public void testMethod(OrganizationServiceProxy service) {
        service.Timeout = new TimeSpan(0, 15, 0);
    }

}

This is after the refactor. I've tried casting IOrganizationService to OrganizationServiceProxy, but the faked service context can't handle this cast. An exception is thrown.

class testClass () {

    public void testMethod(IOrganizationService service) {
        var serviceProxy = (OrganizationServiceProxy) service; //This breaks when given a fake context
        service.Timeout = new TimeSpan(0, 15, 0);
    }

}

I've tried using an IOrganizationServiceFactory, as suggested in this post . The problem is, factory.CreateOrganizationService() generates an IOrganizationService, not an OrganizationSeriviceProxy.

How can I refactor to use IOrganizationService instead of OrganizationServiceProxy without losing functionality? I'm guessing I might have to implement the IOrganizationService as an OrganizationServiceProxy somehow.

Two options:

1) To keep it simple, refactor your code so that it references IOrganizationService only, and only use that code in your tests, and leave the TimeOut bit untested (outside of the scope of the refactored functions)

2) If unit testing the Timeout property is really necessary, mock your own OrganizationServiceContext class and pass the mock service generated by FakeXrmEasy (IOrganizationService) to the OrganizationServiceProxy's constructor. Here's a list of all the available the constructors:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.client.organizationserviceproxy.-ctor?view=dynamics-general-ce-9

Could something like this be viable?

public class OrganizationServiceProxy : IServiceProxy
  {
    public int SomeProp
    {
      get
      {
        return 1;
      }

      set
      {
      }
    }

    public TimeSpan Timeout
    {
      get
      {
        return new TimeSpan();
      }

      set
      {
      }
    }

    public void SomeMethod()
    {
    }
  }
  public interface IServiceProxy : IOrganizationService
  {
    TimeSpan Timeout { get; set; }
  }

  public interface IOrganizationService
  {
    void SomeMethod();
    int SomeProp { get; set; }
  }

Since OrganizationServiceProxy implements IServiceProxy (which in turn implements IOrganizationService) you could check if the object you passed in implements the IServiceProxy interface and do your work inside of the if.

private void testMethod(IOrganizationService someService)
{
   if(someService is IServiceProxy)
   {
     IServiceProxy tempProxy = someService as IServiceProxy;
     tempProxy.Timeout = new TimeSpan();
   }
}

I am not sure if this would help, but this is what I used

CrmServiceClient c = new CrmServiceClient(connectionstring); //various parameters available
(OrganizationServiceProxy) service = c.OrganizationWebProxyClient ?? c.OrganizationServiceProxy;

I think there is an easy solution - if you don't need to mock the methods over OrganizationServiceProxy - just ignore those in unit testing context.

IE instead of

// This breaks when given a fake context
var serviceProxy = (OrganizationServiceProxy) service;
serviceProxy.Timeout = new TimeSpan(0, 15, 0);

Do

var serviceProxy = service as (OrganizationServiceProxy);
// The serviceProxy is null so it is ignored when given a fake context
if (serviceProxy != null)
{
   serviceProxy.Timeout = new TimeSpan(0, 15, 0);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM