FakeItEasy - 检索伪造的对象

FakeItEasy - Retrieve Faked object

有什么方法可以检索插入到伪造的 class 中的伪造对象?

例如

假设我有以下界面 + class;

public interface IFakeable
{
    void FakeYou();
}

public class SomeClass
{
    private readonly IFakeable _fake;

    public SomeClass(IFakeable fake)
    {
        _fake = fake;
    }

    public void FakeCall()
    {
        _fake.FakeYou();
    }
}

并想测试如下内容:

[TestFixture]
public class SomeClassTests
{
    [Test]
    public void FakeCall_CallsIFakeabl_FakeYou()
    {
        var subject = A.Fake<SomeClass>();

        subject.FakeCall();

        A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();
    }
}

在不公开 SomeClass._fake 字段的情况下这可能吗?

有什么地方我可以指定使用单例来伪造吗?

这里更重要的是为什么您要测试在私有字段上调用的方法。私有字段封装在 class 中,因此该方法对该字段所做的任何操作都构成 "internals of the class" 并且与测试无关。我假设 FakeYou() 实现有一些需要测试的重要副作用。在那种情况下,我会在 subject.FakeCall() 之后测试该副作用,而不是测试是否发生了 FakeCall。

或者,您可以将 _fake 更改为 public 字段,然后更改:

A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();

至:

A.CallTo(() => subject._fake.FakeYou()).MustHaveHappened();

如果这是 C# 约定的情况,您可能希望将“_fake”重命名为 "Fake",正如 ReSharper 会告诉您的那样。

如果测试的主题是SomeClass,你为什么要伪造它?你想测试真正的 class,而不是假的......所以你应该这样做:

[Test]
public void FakeCall_CallsIFakeabl_FakeYou()
{
    var fake = A.Fake<IFakeable>();
    var subject = new SomeClass(fake);

    subject.FakeCall();

    A.CallTo(() => fake.FakeYou()).MustHaveHappened();
}

或者,您可以使用 FakeItEasy 的 fixture initialization feature:

[TestFixture]
public class SomeClassTests
{
    [Fake] public IFakeable Fake {get;set;}

    [UnderTest] public SomeClass Subject {get;set;}

    [SetUp]
    public void Setup()
    {
        Fake.InitializeFixture(this);
    }

    [Test]
    public void FakeCall_CallsIFakeabl_FakeYou()
    {
        Subject.FakeCall();

        A.CallTo(() => Fake.FakeYou()).MustHaveHappened();
    }
}