如何使用 FakeItEasy 伪造 Base Class 方法
How can I Fake Base Class method using FakeItEasy
我正在尝试使用 FakeItEasy。我有一个特定的场景,要么无法理解如何测试,要么无法使用 FakeItEasy
假设我有一个基础 class 和派生的 class 看起来像这样
public class BaseClass {
protected bool BaseClassMethod() { return true; }
}
public class DerivedClass : BaseClass {
public void DoSomething(){
if(BaseClassMethod()) Console.WriteLine("Bla");
else Console.WriteLine("Worked");
}
}
现在我希望能够测试 DerivedClass,但能够伪造 BaseClassMethod()。我尝试做类似
的事情
var fakeBaseClass = A.Fake<BaseClass>();
A.CallTo(fakedBaseClass).Where(x => x.Method.Name "BaseClassMethod")).WithReturnType<bool>(). Returns(false);
var derivedClass = new DerivedClass(); // Am hoping that the DerivedClass will use the Faked Baseclass that I have created above.
derivedClass.DoSomething()
这不符合我的预期。我是不是遗漏了什么或者 FakeItEasy 不可能做到这一点?
谢谢
卡尔提克
您的方法存在一些问题。
第一个问题是你创建的fakeBaseClass
和derivedClass
之间没有任何联系,所以他们没有办法相互影响。为了完成我认为你正在尝试做的事情,你真的想制作一个假的 DerivedClass
并操纵它的行为(实际上,一般来说,这种类型的测试是有争议的,但让我们关注机制并搁置是否现在这是个好主意)。
通过伪造 DerivedClass
,FakeItEasy 实际上将实例化一种新类型的 class, 派生自 DerivedClass
,因此将调用和可以访问 DerivedClass
和 BaseClass
的所有(受保护或 public)方法。然后你可以从 BaseClassMethod
设置你想要的行为并练习 DoSomething
并希望得到你想要的结果。
当我们尝试这个时会导致问题的第二件事是 BaseClassMethod
不是虚拟的。 FakeItEasy(及其同类的隔离框架)无法伪造任何非虚拟的方法。您可以在 What can be faked.
了解更多关于什么是可伪造的
因此,将这两个更改放在一起,我得到如下代码:
public class BaseClass
{
protected virtual bool BaseClassMethod()
{
return true;
}
}
public class DerivedClass : BaseClass
{
public string DoSomething()
{
if (BaseClassMethod())
{
return ("Bla");
}
else
{
return ("Worked");
}
}
}
[Test]
public void MethodName_StateUnderTest_ExpectedBehavior()
{
var fakedDerivedClass = A.Fake<DerivedClass>();
A.CallTo(fakedDerivedClass)
.Where(x => x.Method.Name == "BaseClassMethod")
.WithReturnType<bool>()
.Returns(false);
Assert.That(fakedDerivedClass.DoSomething(), Is.EqualTo("Worked"));
}
本次测试通过。请注意,我已经对您的原件进行了更改(除了更正拼写错误):
BaseClassMethod
现在是虚拟的
- 我正在创建一个假的
DerivedClass
用于测试,
DoSomething
returns 一个字符串,而不是写入控制台。这不是绝对必要的,但让我的测试更容易编写。
请注意,如果 BaseClassMethod
不是虚拟的,那么除了 true
之外,它不可能 return 任何东西,而且我认为编写测试没有多大意义看看 DoSomething
从中得到 false
会发生什么。
有关为什么伪造 class 被测者(而不是 class 的 合作者 )可能不是一个好主意的更多讨论,请参阅评论在 Use FakeItEasy's A.CallTo() on another method in same object and my answer to Using FakeItEasy, is it possible to create a dummy object of a type that takes generic type parameters.
但是您对这种方法的感受是您必须自己接受的。
我正在尝试使用 FakeItEasy。我有一个特定的场景,要么无法理解如何测试,要么无法使用 FakeItEasy
假设我有一个基础 class 和派生的 class 看起来像这样
public class BaseClass {
protected bool BaseClassMethod() { return true; }
}
public class DerivedClass : BaseClass {
public void DoSomething(){
if(BaseClassMethod()) Console.WriteLine("Bla");
else Console.WriteLine("Worked");
}
}
现在我希望能够测试 DerivedClass,但能够伪造 BaseClassMethod()。我尝试做类似
的事情var fakeBaseClass = A.Fake<BaseClass>();
A.CallTo(fakedBaseClass).Where(x => x.Method.Name "BaseClassMethod")).WithReturnType<bool>(). Returns(false);
var derivedClass = new DerivedClass(); // Am hoping that the DerivedClass will use the Faked Baseclass that I have created above.
derivedClass.DoSomething()
这不符合我的预期。我是不是遗漏了什么或者 FakeItEasy 不可能做到这一点?
谢谢 卡尔提克
您的方法存在一些问题。
第一个问题是你创建的fakeBaseClass
和derivedClass
之间没有任何联系,所以他们没有办法相互影响。为了完成我认为你正在尝试做的事情,你真的想制作一个假的 DerivedClass
并操纵它的行为(实际上,一般来说,这种类型的测试是有争议的,但让我们关注机制并搁置是否现在这是个好主意)。
通过伪造 DerivedClass
,FakeItEasy 实际上将实例化一种新类型的 class, 派生自 DerivedClass
,因此将调用和可以访问 DerivedClass
和 BaseClass
的所有(受保护或 public)方法。然后你可以从 BaseClassMethod
设置你想要的行为并练习 DoSomething
并希望得到你想要的结果。
当我们尝试这个时会导致问题的第二件事是 BaseClassMethod
不是虚拟的。 FakeItEasy(及其同类的隔离框架)无法伪造任何非虚拟的方法。您可以在 What can be faked.
因此,将这两个更改放在一起,我得到如下代码:
public class BaseClass
{
protected virtual bool BaseClassMethod()
{
return true;
}
}
public class DerivedClass : BaseClass
{
public string DoSomething()
{
if (BaseClassMethod())
{
return ("Bla");
}
else
{
return ("Worked");
}
}
}
[Test]
public void MethodName_StateUnderTest_ExpectedBehavior()
{
var fakedDerivedClass = A.Fake<DerivedClass>();
A.CallTo(fakedDerivedClass)
.Where(x => x.Method.Name == "BaseClassMethod")
.WithReturnType<bool>()
.Returns(false);
Assert.That(fakedDerivedClass.DoSomething(), Is.EqualTo("Worked"));
}
本次测试通过。请注意,我已经对您的原件进行了更改(除了更正拼写错误):
BaseClassMethod
现在是虚拟的- 我正在创建一个假的
DerivedClass
用于测试, DoSomething
returns 一个字符串,而不是写入控制台。这不是绝对必要的,但让我的测试更容易编写。
请注意,如果 BaseClassMethod
不是虚拟的,那么除了 true
之外,它不可能 return 任何东西,而且我认为编写测试没有多大意义看看 DoSomething
从中得到 false
会发生什么。
有关为什么伪造 class 被测者(而不是 class 的 合作者 )可能不是一个好主意的更多讨论,请参阅评论在 Use FakeItEasy's A.CallTo() on another method in same object and my answer to Using FakeItEasy, is it possible to create a dummy object of a type that takes generic type parameters.
但是您对这种方法的感受是您必须自己接受的。