简体   繁体   English

不使用Rhino嘲笑的界面模拟服务

[英]Mock service without interfaces using rhino mocks

Background My application is consuming a WCF service via proxyies. 背景信息我的应用程序通过代理使用WCF服务。 I have to unit test my implementation, that it consume the service and processing are done correctly. 我必须对实现进行单元测试,以确认它消耗了服务,并且处理正确完成了。

Method to be Tested 测试方法

public class MyClass
{ 
 private ManagerServiceClientImpl myclient;

 public void MethodToBeTested();
 {
    var result = GetServiceData();
    if(result!=null)
       //some processing
 }
}

private MyObject GetServiceData()
{
    myclient = ServiceLocator.Current.GetInstance<ManagerServiceClientImpl>();
    if(myclient.ConnectToService() && myclient.MyServiceClient.IsConnected)
       return myclient.GetData();
    else
     return null;
}

This is provided by external source, so I have no right to modify it 这是由外部来源提供的,因此我无权对其进行修改

public class ManagerServiceClientImpl
{
  public ServiceClient MyServiceClient { get; private set; }
  public bool ConnectToService()
}

How would I mock the ManagerServiceClientImpl it doesn't have interface or methods are not marked as virtual 我该如何模拟没有接口或方法未标记为虚拟的ManagerServiceClientImpl

What i tried so far. 到目前为止我尝试过的。

[TestMethod]
public void IsServiceConnected_GetData()
{

  //Arrange
  ManagerServiceClientImpl clientImpl = 
               MockRepository.GenerateMock<ManagerServiceClientImpl>();

  ServiceLocator.Expect(x => x.GetInstance<ManagerServiceClientImpl>())
                .Return(clientImpl);

  var testData= new MyObject 
  {
            ID = "Test1",
            Name ="test",
  }

  //Act
  _myClass.MethodToBeTested();

  //Assert
  stubService.AssertWasCalled(h => h.SaveAllChanges());
}

Note: Using Rhino.Mocks. 注意:使用Rhino.Mocks。 Its my first time using Rhino mocks 这是我第一次使用Rhino模拟

As Amittai Shapira mentioned you can mock it without an interface by using unit testing frameworks that support it, i'm using Typemock Isolator and i created an example test for your code: 正如Amittai Shapira所提到的,您可以通过使用支持接口的单元测试框架来模拟它而无需使用接口,我正在使用Typemock Isolator,并且为您的代码创建了一个示例测试:

I've created an instance of MyClass and used a feature of Typemock to mock Non-Public methods to change the return value for GetServiceData 我已经创建了MyClass的实例,并使用Typemock的功能来模拟非公共方法来更改GetServiceData的返回值。

[TestMethod]
public void TestMethod1()
{
    var testData = new MyObject
    {
        ID = "Test1",
        Name = "test",
    };

    var realObj = new MyClass();
    Isolate.NonPublic.WhenCalled(realObj, "GetServiceData").WillReturn(testData);
    Isolate.NonPublic.WhenCalled(realObj, "SaveAllChanges").CallOriginal();

    realObj.MethodToBeTested();

    Isolate.Verify.NonPublic.WasCalled(realObj, "SaveAllChanges");
}

In order to use RhinoMocks (or Moq, or any other "constrained" mocking framework), the type you are mocking must support inheritance on the members you want to mock. 为了使用RhinoMocks(或Moq或任何其他“受约束的”模拟框架),您要模拟的类型必须支持要模拟的成员的继承。 This means it must either be an interface, or the members must be virtual/abstract. 这意味着它必须是接口,或者成员必须是虚拟/抽象的。 Without that, these frameworks cannot do what they need to do to generate a proxy middle-man at runtime. 否则,这些框架将无法做它们在运行时生成代理中间人所需的工作。 For more details, see my blog post on how .NET mocking frameworks work under the hood: https://www.wrightfully.com/how-net-mocking-frameworks-work 有关更多详细信息,请参阅我的博客文章有关.NET模拟框架如何在幕后工作: https//www.wrightfully.com/how-net-mocking-frameworks-work

What you could do is create methods in your own class that wrap the other service such that you could mock your methods and have them return whatever you need, completely bypassing the service. 可以做的是在自己的类中创建包装其他服务的方法,以便您可以模拟您的方法并使它们返回所需的内容,从而完全绕开该服务。

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

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