FakeItEasy - Получить поддельный объект

Есть ли способ получить поддельные объекты, которые были вставлены в поддельный класс?

E.g.

Скажем, у меня есть следующий интерфейс + класс;

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?

Могу ли я где-нибудь указать, чтобы использовать синглтоны для подделок?


person Michal Ciechan    schedule 28.04.2016    source источник


Ответы (2)


Если предметом теста является 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. функция инициализации прибора:

[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();
    }
}
person Thomas Levesque    schedule 28.04.2016

Что более важно здесь, так это то, почему вы хотите протестировать метод, который вызывается в частном поле. Закрытое поле инкапсулировано в классе, поэтому все, что метод делает с этим полем, является «внутренностями класса» и не имеет отношения к тестированию. Я предполагаю, что реализация FakeYou() имеет важный побочный эффект, требующий тестирования. В этом случае я бы проверил этот побочный эффект после subject.FakeCall(), а не проверял, что FakeCall произошел.

В качестве альтернативы вы можете сделать _fake общедоступным полем и изменить:

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

to:

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

Возможно, вы захотите переименовать «_fake» в «Fake», если это относится к соглашениям C#, как сообщит вам ReSharper.

person GDubz    schedule 28.04.2016
comment
Причина, по которой я спрашиваю, заключается в том, что часто я хочу проверить, что, например, SaveChanges() вызывается в контексте EF. Я нашел FakeItEasyAutoMocker, который я создал (Moqqer) для Moq. Так что думаю, что нет поддержки для этого из коробки. - person Michal Ciechan; 28.04.2016