如何在我正在测试的方法中模拟函数调用 - 当前使用 NSubsitute

How to mock a function call in the method I am testing - currently using NSubsitute

我不熟悉在单元测试中模拟事物...

为发布而简化的示例代码:

namespace MockInvestigate.Monitor
{
    internal interface IAgentRepo
    {
        Dictionary<string, string> GetAgentAppSettings(string moduleName);
    }

    public class AgentRepo : IAgentRepo
    {
        public virtual Dictionary<string, string> GetAgentAppSettings(string moduleName)
        {
            return new Dictionary<string, string> { { "real", "data" } };
        }
    }
}

这是我想要进行单元测试的方法 - 但覆盖了对 GetAgentAppSettings 的调用

namespace MockInvestigate
{
    public class Class1
    {
        public static bool IsInitialized(string taskName)
        {
            AgentRepo ar = new AgentRepo();
            var arReturn = ar.GetAgentAppSettings(taskName);

            return arReturn.ContainsKey("real");
        }
    }
}

单元测试 - 试图模拟对 'GetAgentAppSettings'

的调用
[TestMethod]

public void TestMethod1()
{
 var repo = Substitute.ForPartsOf<AgentRepo>();
 var appReturn = new Dictionary<string, string> { { "bogus", "bogus2" } };
 repo.GetAgentAppSettings("somevalue").ReturnsForAnyArgs(appReturn);

 bool retValue = Class1.IsInitialized("somevalue");

 Assert.IsFalse(retValue);
}

当我的测试是 运行 时,真正的 GetAgentAppSettings 被调用,返回 "real"、"data" 而不是我想要的虚假数据。 我试过了 .When(...).DoNotCallBase().

我的测试可以修改以工作吗?底层代码是否需要更改才能工作?

如有任何帮助,我们将不胜感激。

创建替代品 repo 后,您必须将其注入 Class1。 但是,在您的代码中,您在 IsInitialized 方法中创建了 AgentRepo,因此它没有使用您在测试方法中创建的替代方法。

您必须通过构造函数注入、属性 注入或方法注入来注入替代品。

顾名思义,构造函数注入就是从构造函数中注入依赖项。由于方法 IsInitialized 是静态的,所以这不是一个选项。

同样,属性 注入使用属性来注入依赖项。您可以创建一个静态 属性,但通常您会远离它。 它总是为每个线程使用相同的实例,因此您必须保证 AgentRepo 是线程安全的。

不得已,您可以使用方法注入。您将获得 AgentRepo 实例作为方法参数,并让调用者负责创建它。

由于这是一个小的复现,我不能告诉你什么是最好的处理方法。我所知道的是 AgentRepo 必须以某种方式注入 Class1