#unit-testing #fakeiteasy
Вопрос:
Я новичок в FakeItEasy, извините, если решение очевидно.
Это упрощенный код, который воспроизводит проблему:
У меня есть базовый класс:
public abstract class BaseClass
{
public void Do()
{
Do_Override();
}
protected abstract void Do_Override();
}
и производный:
public class ImplementingClass: BaseClass
{
protected override void Do_Override()
{
ProtectedDo();
}
protected virtual void ProtectedDo()
{
}
}
В своем тесте я хочу посмотреть, был ли ProtectedDo()
вызван. Я пытался протестировать двумя способами, но тесты проваливаются с одним и тем же сообщением:
1-й. В режиме отладки он не входит в Do_Override()
public class ImplementingClassShould
{
[Fact]
public void Run_ProtectedDo()
{
var fake = A.Fake<ImplementingClass>();
fake.Do();
A.CallTo(fake).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();
}
}
2-е место. В режиме отладки он входит в Do_Override()
public class ImplementingClassShould
{
[Fact]
public void Run_ProtectedDo_V2()
{
var sut = new ImplementingClass();
var sutFakeWrapper = A.Fake<ImplementingClass>(_ => _.Wrapping(sut));
sutFakeWrapper.Do();
A.CallTo(sutFakeWrapper).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();
}
}
Сообщение об ошибке:
Комментарии:
1. Привет, @fmm. Мне нравится упрощенное повторение, но, как правило, неплохо указать, что пошло не так в вашем опыте. Например, почему вы не думаете, что ваш код работает?
2. Привет, @BlairConrad. Я обновил свой вопрос сообщением о провале теста. Также моя 2-я попытка проверить. Спасибо.
Ответ №1:
Ваш тест совершенно хорош, насколько это возможно. Если вы запустите его, он сообщит вам, что ProtectedDo
это не было вызвано, что является точным. Поскольку Do_Override
это виртуально, FakeItEasy перехватывает вызов. (Защищенность в данном случае не влияет на вещи.)
Если вы не хотите Do_Override
, чтобы вас перехватил FakeItEasy, вам следует настроить подделку для вызова базового метода вместо обработки самого вызова:
[Fact]
public void Run_ProtectedDo()
{
var fake = A.Fake<ImplementingClass>();
A.CallTo(fake).Where(_ => _.Method.Name == "Do_Override").CallsBaseMethod();
fake.Do();
A.CallTo(fake).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();
}
Обновление в свете недавно добавленного Run_ProtectedDo_V2
теста:
Я ожидаю, что вы уже знаете это, @fmm, но тест все равно проваливается. Это происходит потому, что, когда sutFakeWrapper.Do
вызывается, он перенаправляется на завернутый sut.Do
. Поскольку sut
это конкретный ImplementingClass
, он вызывает свой Do_Override
, который вызывает свой ProtectedDo
, поэтому его можно отлаживать в ProtectedDo
вызов метода. Только это sut.ProtectedDo
не sutFakeWrapper.ProtectedDo
так . Отсюда и провал теста.