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

时间:2016-02-19 17:11:03

标签: c# unit-testing mocking nsubstitute

我是新手,试图在单元测试中模拟事物......

简化发布的示例代码:

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&#39;

的调用
[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,返回&#34;真实&#34;,&#34;数据&#34;而不是我想要的伪造数据。 我试过.When(...).DoNotCallBase()

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

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

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

您必须通过构造函数注入,属性注入或方法注入来注入替换。

顾名思义,构造函数注入就是从构造函数中注入依赖项。由于方法IsInitialized是静态的,因此不是一种选择。

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

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

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