1

我正在尝试重构我的代码,以便我可以使用 fakexrmeasy 进行单元测试。

作为此处提到的建议重构的一部分,我尝试将 IOrganizationService 传递到我的所有类和方法中。但是,我的一些类使用了 IOrganizationService 没有的变量和方法,例如 Timeout。我正在尝试找到一种方法来重构使用 IOrganizationService 而不会丢失功能。

这就是它在重构之前的存在方式。

class testClass () {

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

}

这是重构之后。我尝试将 IOrganizationService 强制转换为 OrganizationServiceProxy,但伪造的服务上下文无法处理此强制转换。抛出异常。

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

}

我试过使用 IOrganizationServiceFactory,正如这篇文章中所建议的那样。问题是,factory.CreateOrganizationService() 生成的是 IOrganizationService,而不是 OrganizationServiceProxy。

如何在不丢失功能的情况下重构以使用 IOrganizationService 而不是 OrganizationServiceProxy?我猜我可能不得不以某种方式将 IOrganizationService 实现为 OrganizationServiceProxy。

4

4 回答 4

1

两种选择:

1) 为简单起见,重构您的代码,使其仅引用 IOrganizationService,并且仅在您的测试中使用该代码,并使 TimeOut 位未经测试(超出重构函数的范围)

2) 如果确实需要对 Timeout 属性进行单元测试,请模拟您自己的 OrganizationServiceContext 类,并将 FakeXrmEasy (IOrganizationService) 生成的模拟服务传递给 OrganizationServiceProxy 的构造函数。以下是所有可用构造函数的列表:

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

于 2020-01-28T13:10:57.263 回答
0

我不确定这是否会有所帮助,但这就是我使用的

CrmServiceClient c = new CrmServiceClient(connectionstring); //various parameters available
(OrganizationServiceProxy) service = c.OrganizationWebProxyClient ?? c.OrganizationServiceProxy;
于 2019-05-30T08:10:46.893 回答
0

这样的事情是否可行?

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

由于 OrganizationServiceProxy 实现了 IServiceProxy(而后者又实现了 IOrganizationService),您可以检查您传入的对象是否实现了 IServiceProxy 接口并在 if 中执行您的工作。

private void testMethod(IOrganizationService someService)
{
   if(someService is IServiceProxy)
   {
     IServiceProxy tempProxy = someService as IServiceProxy;
     tempProxy.Timeout = new TimeSpan();
   }
}
于 2019-05-29T20:32:19.440 回答
0

我认为有一个简单的解决方案 - 如果您不需要模拟这些方法OrganizationServiceProxy- 只需忽略单元测试上下文中的那些。

IE而不是

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

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);
}
于 2019-05-31T17:25:08.470 回答