【问题标题】:FakeItEasy - Retrieve Faked objectFakeItEasy - 检索伪造的对象
【发布时间】:2016-04-28 19:17:00
【问题描述】:

有没有办法检索插入到伪造类中的伪造对象?

例如

假设我有以下接口+类;

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 字段的情况下这是否可行?

有什么地方我可以指定使用 Singletons for Fakes 吗?

【问题讨论】:

    标签: c# testing mocking tdd fakeiteasy


    【解决方案1】:

    如果测试的对象是SomeClass,那你为什么要装呢?你想测试真实的类,而不是假的......所以你应该这样做:

    [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();
        }
    }
    

    【讨论】:

      【解决方案2】:

      这里更重要的是为什么您要测试在私有字段上调用的方法。私有字段被封装在类中,因此该方法对该字段所做的任何事情都构成“类的内部”并且与测试无关。我认为 FakeYou() 实现有一些需要测试的重要副作用。在这种情况下,我会在 subject.FakeCall() 之后测试该副作用,而不是测试 FakeCall 是否发生。

      或者,您可以将 _fake 更改为公共字段,并更改:

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

      到:

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

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

      【讨论】:

      • 我问的原因是,因为我经常想检查是否在 EF 上下文中调用了 SaveChanges()。我发现 FakeItEasyAutoMocker 与我为 Moq 创建的 (Moqqer) 相同。所以猜测没有开箱即用的支持。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      相关资源
      最近更新 更多