在单元测试时进行企业框架调用

Making an Enterprise Framework Call while Unit Testing

这是我们正在做的事情的基本思路:

一切顺利。但是,C 有一些额外的要求。向此服务提交 XML 时,其中一个 XML 元素需要进行广泛的查找。我们决定将该查找所需的数据添加到我们数据库中的 table。因此,XMLStringC 中有一个私有方法,它使用 EF 进行数据库调用并获取所需的数据以添加到 XML 字符串。

我有点意识到这样做违反了单一职责原则,因为这些 classes 除了构建 XML 字符串之外什么都不应该做。 A 和 B classes 不调用数据库。

当我尝试进行单元测试以测试 A、B 和 C 时,我的所作所为可能是愚蠢的。因为我们不在上下文中,当 运行 单元测试时,C尝试调用数据库时失败。

我不确定在哪里为 C 执行此自定义逻辑。一方面,它仅在我们要提交给 C 服务时发生,因此在 C 中执行此操作很有意义 class.另一方面,我不喜欢从 class 内部进行数据库调用。最终这可能并不重要,如果我能弄清楚如何对其进行单元测试并使其工作。

执行此操作的最佳实践方法是什么?

If I did that, then A,B and C would all need it. But A and B don't care about it. They all implement the same interface.

如果您遵循依赖项注入最佳实践,则您的依赖项不是接口的一部分,而是对象构造函数的一部分。

您的评估是正确的,这违反了 SRP。您需要的是一种执行查找的服务,该服务作为依赖项传递到 C 中。那么您的服务不会违反 SRP,您仍然可以对 XMLStringC class.

进行单元测试
public class XMLStringB : IFooInterface
{
    // No constructor defined here - we have no dependencies

    public string GenerateXML(FooObject fooObject)
    {
        // implementation here
    }

    public void ParseResponse(string serviceCallResponse)
    {
        // implementation here
    }
}

public class XMLStringC : IFooInterface
{
    private readonly IDatabaseLookupService databaseLookupService;

    public XMLStringC(IDatabaseLookupService databaseLookupService)
    {
        if (databaseLookupService == null)
            throw new ArgumentNullException("databaseLookupService");
        this.databaseLookupService = databaseLookupService;
    }

    public string GenerateXML(FooObject fooObject)
    {
        // Use this.databaseLookupService as needed.
        var data = this.databaseLookupService.Lookup(fooObject.ID);

        // implementation here
    }

    public void ParseResponse(string serviceCallResponse)
    {
        // Use this.databaseLookupService as needed.
        var data = this.databaseLookupService.Lookup(someID);

        // implementation here
    }
}

您对数据库的依赖将转移到 IDatabaseLookupService,而不是绑定到您的业务逻辑。