Moq 正在进行方法调用和 returning 真实数据,而不是 Setup 中的 return 数据
Moq is making method call and returning real data, and not the return data in Setup
我正在尝试 return 静态声明的 NWatchNativeNode[] 数组,但 Moq 似乎实际上是在调用用于获取真实系统数据的真实方法。是不是下面的设置不正确?
我想确定什么时候
GetNodesInCriticalCondition()
被调用,criticalNodes1
被return编辑。
单元测试代码
var criticalNodes1 = new NWatchNativeNode[]
{
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch",
"MyAlias",
12345
),
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch2",
"MyAlias2",
54321
),
};
var mock = new Mock<NWatchCasModelStatusScheduleEntry>(_application);
mock.Setup(x => x.GetNodesInCriticalCondition()).Returns(criticalNodes1);
var nodes = mock.Object.GetNodesInCriticalCondition();
Assert.AreEqual(2, nodes.Length); // This should return true
根据您的要求,这里有一个如何使用 Moq 进行测试的快速示例。
让我们先做一些 classes 和接口来测试。
public interface IFoo
{
IEnumerable<int> GetFoos();
}
public class Foo : IFoo
{
public IEnumerable<int> GetFoos()
{
return Enumerable.Range(1, 10);
}
}
public class Bar
{
private readonly IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public IEnumerable<int> SquareFoos()
{
foreach(var item in foo.GetFoos())
{
yield return item * item;
}
}
}
现在,Bar
依赖于 IFoo
接口。现在我们想在 Bar
class 上测试 SquareFoos
的功能。这是我们正在测试的主题。我们要模拟的是传递给Bar
的构造函数的IFoo
接口。这为我们提供了以下单元测试设置。
// Arrange
var mock = new Mock<IFoo>();
mock.Setup(m => m.GetFoos()).Returns(Enumerable.Range(1, 2));
var sut = new Bar(mock.Object);
// Act
var results = sut.SquareFoos().ToList();
// Assert
Assert.AreEqual(2, results.Count);
在这种情况下,我们模拟了 GetFoos
returns 以允许我们测试我们的 Bar
class.
Mock
returns 真实系统数据的最可能原因是您的方法 GetNodesInCriticalCondition()
未声明 [=12=]。
为了Moq
能够设置方法调用,这些方法必须是virtual
,否则无法覆盖它们,因此无法拦截它们,这导致原始方法被调用。
编辑:
如果您的方法是 internal
,您必须将其访问权限授予 单元测试项目 和 Moq.
您可以通过添加
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
和
[assembly: InternalsVisibleTo("TestProjectNameSpace")]
到您正在为其创建模拟的项目的 AssemblyInfo.cs
文件。
我正在尝试 return 静态声明的 NWatchNativeNode[] 数组,但 Moq 似乎实际上是在调用用于获取真实系统数据的真实方法。是不是下面的设置不正确?
我想确定什么时候
GetNodesInCriticalCondition()
被调用,criticalNodes1
被return编辑。
单元测试代码
var criticalNodes1 = new NWatchNativeNode[]
{
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch",
"MyAlias",
12345
),
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch2",
"MyAlias2",
54321
),
};
var mock = new Mock<NWatchCasModelStatusScheduleEntry>(_application);
mock.Setup(x => x.GetNodesInCriticalCondition()).Returns(criticalNodes1);
var nodes = mock.Object.GetNodesInCriticalCondition();
Assert.AreEqual(2, nodes.Length); // This should return true
根据您的要求,这里有一个如何使用 Moq 进行测试的快速示例。
让我们先做一些 classes 和接口来测试。
public interface IFoo
{
IEnumerable<int> GetFoos();
}
public class Foo : IFoo
{
public IEnumerable<int> GetFoos()
{
return Enumerable.Range(1, 10);
}
}
public class Bar
{
private readonly IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public IEnumerable<int> SquareFoos()
{
foreach(var item in foo.GetFoos())
{
yield return item * item;
}
}
}
现在,Bar
依赖于 IFoo
接口。现在我们想在 Bar
class 上测试 SquareFoos
的功能。这是我们正在测试的主题。我们要模拟的是传递给Bar
的构造函数的IFoo
接口。这为我们提供了以下单元测试设置。
// Arrange
var mock = new Mock<IFoo>();
mock.Setup(m => m.GetFoos()).Returns(Enumerable.Range(1, 2));
var sut = new Bar(mock.Object);
// Act
var results = sut.SquareFoos().ToList();
// Assert
Assert.AreEqual(2, results.Count);
在这种情况下,我们模拟了 GetFoos
returns 以允许我们测试我们的 Bar
class.
Mock
returns 真实系统数据的最可能原因是您的方法 GetNodesInCriticalCondition()
未声明 [=12=]。
为了Moq
能够设置方法调用,这些方法必须是virtual
,否则无法覆盖它们,因此无法拦截它们,这导致原始方法被调用。
编辑:
如果您的方法是 internal
,您必须将其访问权限授予 单元测试项目 和 Moq.
您可以通过添加
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
和
[assembly: InternalsVisibleTo("TestProjectNameSpace")]
到您正在为其创建模拟的项目的 AssemblyInfo.cs
文件。