简体   繁体   English

如何重构方法以用 IOrganizationService 替换 OrganizationServiceProxy

[英]How to refactor method to replace OrganizationServiceProxy with IOrganizationService

I'm attempting to refactor my code so that I can unit test using fakexrmeasy.我正在尝试重构我的代码,以便我可以使用 fakexrmeasy 进行单元测试。

As part of the suggested refactor mentioned here , I've attempted to pass IOrganizationService into all of my classes and methods.作为此处提到的建议重构的一部分,我尝试将 IOrganizationService 传递到我的所有类和方法中。 However, some of my classes use variables and methods that IOrganizationService doesn't have, such as Timeout.但是,我的一些类使用了 IOrganizationService 没有的变量和方法,例如 Timeout。 I'm trying to find a way to refactor to use IOrganizationService without losing functionality.我正在尝试找到一种方法来重构以使用 IOrganizationService 而不会丢失功能。

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.我已经尝试将 IOrganizationService 转换为 OrganizationServiceProxy,但伪造的服务上下文无法处理此转换。 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 .我已经尝试使用 IOrganizationServiceFactory,正如这篇文章中所建议的那样。 The problem is, factory.CreateOrganizationService() generates an IOrganizationService, not an OrganizationSeriviceProxy.问题是, factory.CreateOrganizationService() 生成 IOrganizationService,而不是 OrganizationServiceProxy。

How can I refactor to use IOrganizationService instead of OrganizationServiceProxy without losing functionality?如何在不丢失功能的情况下重构以使用 IOrganizationService 而不是 OrganizationServiceProxy? I'm guessing I might have to implement the IOrganizationService as an OrganizationServiceProxy somehow.我猜我可能必须以某种方式将 IOrganizationService 实现为 OrganizationServiceProxy。

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) 1) 为简单起见,重构您的代码,使其仅引用 IOrganizationService,并且仅在您的测试中使用该代码,并且不测试 TimeOut 位(在重构函数的范围之外)

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. 2)如果确实需要对Timeout属性进行单元测试,模拟自己的OrganizationServiceContext类,将FakeXrmEasy(IOrganizationService)生成的mock服务传递给OrganizationServiceProxy的构造函数。 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 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.由于 OrganizationServiceProxy 实现了 IServiceProxy(它又实现了 IOrganizationService),您可以检查您传入的对象是否实现了 IServiceProxy 接口并在 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.我认为有一个简单的解决方案 - 如果您不需要通过OrganizationServiceProxy模拟方法 - 只需忽略单元测试上下文中的那些。

IE instead of IE 而不是

// 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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