使用静态类型语言为第三方库创建模拟API?

时间:2009-12-30 02:44:51

标签: c# vb.net api interface

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

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

我面临的一些问题:

  1. RelayClient是NonInheritable / Static。
  2. RelayClient未实现任何接口。
  3. API客户端库是封闭源代码。
  4. 有没有标准的方法来处理这种情况?

2 个答案:

答案 0 :(得分:1)

如果你不想展开你自己的抽象,看看TypeMock Isolator - 它使用探查器钩子来做几乎任何事情的运行时类级别的模拟,无论你是否拥有它。它实际上对类型实现进行了运行时替换,并拦截了所有调用(例如,您不需要对类型进行子类化 - 就CLR而言,您就是类型)。

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

答案 1 :(得分:1)

这样做的方法是让你的代码对抗'中间人'非静态类,它们在内部使用第三方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);
}