如果无法将模拟对象注入方法中,如何触发方法内的特定条件?

问题描述 投票:0回答:1

我必须做什么才能创建一个单元测试,导致searchResultnull,以便MyMethod返回false

public class MyConnectionHandler
    public bool MyMethod()
    {
        var myConnection = new LdapConnection(...);
        var searchResult = myConnection.Search(...);

        if (searchResult == null) return false;
        return true;
    }
}

我遇到这些问题:

  1. 我无法模拟
    myConnection
    ,因为它不是作为依赖项注入的,而且我不喜欢将其设置为可注入的,因为除了 MyConnectionHandler 之外没有其他类会使用它。
  2. Search函数连接到一个外部服务器,我可以将其配置为返回null,但我更喜欢测试依赖于它自己的配置,而不是外部服务器的配置。

我可能需要重构课程,但我不清楚如何正确地做到这一点,我非常感谢你的帮助。

c# unit-testing dependency-injection mocking moq
1个回答
0
投票

如果这行代码

var myConnection = new LdapConnection(...);

以某种方式读取一些您可以拦截的配置信息,如果您可以建立一个内存中的 LDAP 服务器,就像您可以建立一个自动配置的数据库(SQL)服务器一样,您也许可以编写一个集成测试来验证您感兴趣的代码路径。

如果那不可能...

我可能需要重构该类

是的,你这样做,最简单的方法就是注入依赖项,即使你写道你不想这样做。

而且我不想让它可注入,因为除了 MyConnectionHandler 之外没有其他类会使用它。

这可能不是决定注入什么和不注入什么的最佳标准。相反,您应该将那些真正的依赖项建模为接口或基类,仅此而已。这是因为这些是您不可避免的非确定性行为的来源,并且由于您希望测试是确定性的,您希望能够从测试中控制这些依赖项。

因此,

MyConnectionHandler

 应该看起来像这样:

public class MyConnectionHandler private readonly ILdapConnection myConnection; public MyConnectionHandler(ILdapConnection myConnection) { this.myConnection = myConnection; } public bool MyMethod() { var searchResult = myConnection.Search(...); if (searchResult == null) return false; return true; } }
现在您可以创建一个 

Test Double 并将其注入到 MyConnectionHandler

 的实例中。

© www.soinside.com 2019 - 2024. All rights reserved.