NSubstitute 使用 FOrPartsOf 配置 void 方法什么也不做
NSubstitute using FOrPartsOf to configure void method to do nothing
我有一个简单的例子,我想测试一个方法是否在与调用方法相同的 class 上被调用:
public class MyClass
{
public void SomeMethod()
{
SomeSubMethod();
}
public virtual void SomeSubMethod()
{
// do a lot of weird stuff
}
}
public class UnitTest1
{
[Fact]
public void Test1()
{
var target = Substitute.ForPartsOf<MyClass>();
target.Configure().SomeSubMethod(); // <---- please just do nothing
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
}
我的问题是 SomeSubMethod
实际上是在单元测试中调用的,在我的真实代码中我想避免这种情况。
一个简单的解决方法是让 SomeSubMethod
return 一些东西,但现在我正在污染我的真实代码
public class MyClass
{
public void SomeMethod()
{
SomeSubMethod();
}
public virtual int SomeSubMethod()
{
// do a lot of weird stuff
return 0;
}
}
public class UnitTest1
{
[Fact]
public void Test1()
{
var target = Substitute.ForPartsOf<MyClass>();
target.Configure().SomeSubMethod().Returns(0); // <--- Now the real SomeSubMethod won't be invoked
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
}
有没有办法配置 void 方法什么也不做?
你的
/彼得
根据您的描述,我重写了代码:
Public class MyClass
{
public int x = 0; // to verify whether the unit test really execute SomeSubMethod()
public void SomeMethod()
{
SomeSubMethod();
}
public virtual void SomeSubMethod()
{
// do a lot of weird stuff
int x = 10;
}
}
测试是(请注意我使用的是 NUnit 框架):
[TestFixture]
public class UnitTest1
{
[Test]
public void Test2()
{
var myClass = Substitute.For<MyClass>();
myClass.SomeMethod();
myClass.Received(1).SomeSubMethod();
Assert.That(myClass.x, Is.EqualTo(0));
}
}
由于目标测试方法 SomeSubMethod() 是一个虚拟方法,因此您不需要模拟 class MyClass 部分。
这是你想要的吗?
您可以使用 When..Do
语法来处理 void
方法:
public void Test1() {
var target = Substitute.ForPartsOf<MyClass>();
target.When(x => x.SomeSubMethod()).DoNotCallBase(); // <- do not invoke real code
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
另一种选择,假设我们使 SomeMethod
virtual
,是使用标准 Substitute.For<T>
替换所有成员,并选择仅根据您想要的方法调用 base测试。
public void Test2() {
var target = Substitute.For<MyClass>(); // <- substitute all members
target.When(x => x.SomeMethod()).CallBase(); // <- except this one, call the real base implementation for SomeMethod
target.SomeMethod();
target.Received(1).SomeSubMethod();
Assert.Equal(0, target.counter);
}
文档链接:
我有一个简单的例子,我想测试一个方法是否在与调用方法相同的 class 上被调用:
public class MyClass
{
public void SomeMethod()
{
SomeSubMethod();
}
public virtual void SomeSubMethod()
{
// do a lot of weird stuff
}
}
public class UnitTest1
{
[Fact]
public void Test1()
{
var target = Substitute.ForPartsOf<MyClass>();
target.Configure().SomeSubMethod(); // <---- please just do nothing
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
}
我的问题是 SomeSubMethod
实际上是在单元测试中调用的,在我的真实代码中我想避免这种情况。
一个简单的解决方法是让 SomeSubMethod
return 一些东西,但现在我正在污染我的真实代码
public class MyClass
{
public void SomeMethod()
{
SomeSubMethod();
}
public virtual int SomeSubMethod()
{
// do a lot of weird stuff
return 0;
}
}
public class UnitTest1
{
[Fact]
public void Test1()
{
var target = Substitute.ForPartsOf<MyClass>();
target.Configure().SomeSubMethod().Returns(0); // <--- Now the real SomeSubMethod won't be invoked
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
}
有没有办法配置 void 方法什么也不做?
你的 /彼得
根据您的描述,我重写了代码:
Public class MyClass
{
public int x = 0; // to verify whether the unit test really execute SomeSubMethod()
public void SomeMethod()
{
SomeSubMethod();
}
public virtual void SomeSubMethod()
{
// do a lot of weird stuff
int x = 10;
}
}
测试是(请注意我使用的是 NUnit 框架):
[TestFixture]
public class UnitTest1
{
[Test]
public void Test2()
{
var myClass = Substitute.For<MyClass>();
myClass.SomeMethod();
myClass.Received(1).SomeSubMethod();
Assert.That(myClass.x, Is.EqualTo(0));
}
}
由于目标测试方法 SomeSubMethod() 是一个虚拟方法,因此您不需要模拟 class MyClass 部分。
这是你想要的吗?
您可以使用 When..Do
语法来处理 void
方法:
public void Test1() {
var target = Substitute.ForPartsOf<MyClass>();
target.When(x => x.SomeSubMethod()).DoNotCallBase(); // <- do not invoke real code
target.SomeMethod();
target.Received(1).SomeSubMethod();
}
另一种选择,假设我们使 SomeMethod
virtual
,是使用标准 Substitute.For<T>
替换所有成员,并选择仅根据您想要的方法调用 base测试。
public void Test2() {
var target = Substitute.For<MyClass>(); // <- substitute all members
target.When(x => x.SomeMethod()).CallBase(); // <- except this one, call the real base implementation for SomeMethod
target.SomeMethod();
target.Received(1).SomeSubMethod();
Assert.Equal(0, target.counter);
}
文档链接: