如何使现有的公共API可以测试使用它的外部程序员?

时间:2008-12-22 21:45:20

标签: c# .net unit-testing

6 个答案:

答案 0 :(得分:4)

您真正要问的是,“我如何设计具有SOLID和类似原则的API,以便我的API与其他人一起使用?”这不仅仅是可测试性。如果您的客户在使用您的代码测试代码时遇到问题,那么他们在使用您的代码编写/使用代码时也遇到了问题,因此这不仅仅是可测试性,这是一个更大的问题。

简单地提取接口并不能解决问题,因为很可能你现有的类接口(具体类暴露为它们的方法/属性)不是设计时考虑到接口隔离原则,所以提取的接口会有各种各样的接口问题(你在回答前一个答案时提到的一些问题)。

我喜欢称之为IHttpContext问题。正如您所知,ASP.NET很难通过HttpContext.Current的“Magic Singleton Dependency”问题进行测试。没有类似于TypeMock使用的花哨技巧,HttpContext是不可模仿的。简单地提取HttpContext的界面并没有多大帮助,因为它太大了。最终,即使是IHttpContext也会成为测试的负担,所以除了尝试模拟HttpContext本身之外几乎不值得做。

确定对象职责,适当地切换界面和交互,以及使用开放/封闭原则进行设计并不是你想要强制/加入现有的API而不考虑这些原则而设计的。

我不想给你留下如此严峻的答案,所以我会给你一个积极的建议:你如何代表你的客户承担所有的悲伤,并在你的老客户之上做一些服务/门面层API。此服务层必须处理您的API的细节和痛苦,但是会提供一个漂亮,干净,SOLID友好的公共API,您的客户可以使用更少的摩擦。

这还有一个额外的好处,即允许您慢慢替换部分API并最终使其成为新的API不仅仅是一个外观,它是API(并且旧的API被逐步淘汰)。

答案 1 :(得分:2)

另一种方法是创建API的单独分支并在那里执行选项3。然后你只需维护这两个版本并弃用前者。将更改从一个分支合并到另一个分支应该在大多数时间自动运行。

答案 2 :(得分:1)

作为对您的编辑的回复,界面提取确实在这里工作得非常好:

public interface IUserRepository
{
    IUserData GetData(string userName);
}

public class UserRepository 
    : IUserRepository
{
    // The old method is not touched.
    public UserData GetData(string userName)
    {
        ...    
    }

    // Explicitly implement the interface method.
    IUserData IUserRepository.GetData(string userName)
    {
        return this.GetData(userName);
    }
}

正如我在评论中所说,这可能不是每个地方的方式。我认为你应该在API中找出一些要点,让你的客户能够伪造交互并从那里开始是非常重要的。您不必完全重写整个API,但它可以逐步转换。

答案 3 :(得分:0)

您没有提到的一种方法(在大多数情况下我更喜欢的方法)是为您希望API用户能够伪造的类提取接口。不知道你的API,不是每个类都必须提取它的接口。

答案 4 :(得分:0)

第三方用户不应该测试您的API。他们希望针对您的API测试他们的代码,因此他们需要创建API的Mocks等,但他们将依赖于您对API的测试以确保其有效。或者那是你的意思?您想让您的API易于测试吗?

在这种情况下再次开始,这次考虑测试人员:)

答案 5 :(得分:0)

我同意金。为什么不使用您解释的最佳实践重新编写核心API,并提供一组代理/适配器类来公开旧接口但是与您的新API交谈?

自然会鼓励旧开发人员迁移到新的API,但不会被迫立即这样做。新开发人员只会使用您的新API。如果您担心开发人员使用旧API,请宣布旧API接口的EOL。