【问题标题】:Creating a mock API for third party library in statically typed language?用静态类型语言为第三方库创建模拟 API?
【发布时间】:2010-12-30 23:48:52
【问题描述】:

我有一个需要与第三方 API 交互的 VB/C# .NET 应用程序,但我想将其接口出来,以便使用模拟 API 进行测试。以下是我将在代码中使用的示例 API 调用:

RelayClient.AuthenticateUser(username, password, request, sessionID)
RelayClient.GetUserInfo(sessionID)

我面临的几个问题:

  1. RelayClient 是 NonInheritable/Static。
  2. RelayClient 未实现任何接口。
  3. API 客户端库是封闭源代码。

有处理这种情况的标准方法吗?

【问题讨论】:

  • 这是一个长镜头,但如果您的目标程序集中有继承自 MarshalByRefObject 的类,那么许多免费的模拟框架(Moq、RhinoMocks 等)可以模拟它们,即使它们是密封的。不幸的是,他们仍然无法模拟静态类

标签: c# vb.net api interface


【解决方案1】:

如果您不想推出自己的抽象,请查看TypeMock Isolator - 它使用分析器挂钩对几乎任何东西进行运行时类级别的模拟,无论您是否拥有它。它实际上执行类型实现的运行时替换并拦截所有调用(例如,您不需要子类化类型 - 就 CLR 而言,您就是类型)。

这是商业广告,但他们确实提供免费试用。根据您需要模拟的东西有多大,如果它不是基于接口的,那么 799 美元可能非常值得花时间抽象/包装整个 API 表面。

【讨论】:

    【解决方案2】:

    这样做的方法是让您的代码针对“中间人”非静态类工作,这些类在内部使用来自您的 3rd 方 API 的静态类。然后,您可以为单元测试模拟这些“中间人”类。

    类似...(未经测试的代码)

    // your consuming class
    public class MyClass
    {
        private readonly RelayClientManager manager;
    
        public MyClass(RelayClientManager manager)
        {
            this.manager = manager;
        }
    
        public UserInfo GetUserInfo(int sessionID)
        {
            return manager.GetUserInfo(sessionID);
        }    
    }
    
    // 'middle-man' class
    public class RelayClientManager
    {
        public UserInfo GetUserInfo(int sessionID)
        {
            return RelayClient.GetUserInfo(sessionID);
        }
    }
    
    // unit test (using xUnit.net and Moq)
    [Fact]
    public static void GetsUserInfo()
    {
        // arrange
        var expected = new UserInfo();
        var manager = new Mock<RelayClientManager>();
        manager.Setup(x => x.GetUserInfo(0)).Returns(expected);
        var target = new MyClass(manager);        
    
        // act
        var actual = target.GetUserInfo(0);
    
        // assert
        Assert.Equal(expected, actual);
    }
    

    【讨论】:

    • 这与我实现的解决方案非常相似,只是我手动创建了模拟类并填充了固定数据。我将查看 xUnit.net 和 Moq,看看它们是如何工作的。
    • 澄清一下——xUnit.net 是一个单元测试框架,而 Moq 是一个模拟框架。这两个是我各自的最爱,但我所描述的方法也适用于许多其他替代方案,例如NUnit 和 RhinoMocks
    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 2016-09-26
    相关资源
    最近更新 更多