如何在我正在测试的方法中模拟函数调用 - 当前使用 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
。
我不熟悉在单元测试中模拟事物...
为发布而简化的示例代码:
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
。