Утверждение вызова публичного метода в том же экземпляре - PullRequest
5 голосов
/ 14 августа 2011

У меня есть следующий тест

[Test]
public void Attack_TargetWith3Damage_CausesAttackerToDeal3DamageToTarget()
{
    var realAttacker = CreateCreature(damage: 3);
    var wrappedAttacker = A.Fake<ICreature>(x => x.Wrapping(realAttacker));
    var target = A.Fake<ICreature>();
    wrappedAttacker.Attack(target);
    A.CallTo(() => wrappedAttacker.DealDamage(target, 3)).MustHaveHappened();
}

Проблема в том, что вызов DealDamage из метода Attack не регистрируется, потому что внутри метода this равен realAttacker не wrappedAttacker злоумышленник, следовательно, вызов метода не перехватывается.

Как я могу проверить это утверждение?Можно ли это сделать с помощью FakeItEasy?Позволяет ли мне проверить это на другом фреймворке?

Ответы [ 2 ]

3 голосов
/ 14 августа 2011

Вы можете быть очень близки к тому, что вы есть после использования Moq для вашей фальшивой рамки.

Взять это в качестве примера:

public interface ICreature { ... }

public class Creature : ICreature
{
    ... 

    public void Attack(ICreature creature)
    {
        DealDamage(creature, 3); // Hard-coded 3 to simplify example only
    }

    public virtual void DealDamage(ICreature target, int damage) { ... }
}

.... Test ....
var wrappedAttacker = new Mock<Creature>();
var mockTarget = new Mock<ICreature>();

wrappedAttacker.Object.Attack(mockTarget.Object);

wrappedAttacker.Verify(x => x.DealDamage(mockTarget.Object, 3), Times.Once());

В этом случае я «оборачиваю» экземпляр Creature в макет для роли атакующего и создаю макет ICreature для целевой роли. Затем я вызываю метод Attack от атакующего; проверка того, что тот же атакующий DealDamage был вызван (с правильной целью и 3 повреждениями), ровно один раз.

Что делает эту проверку возможной в Moq, так это то, что функция DealDamage помечена virtual. Это может нарушить условия вашей ситуации, но оно затрагивает вопрос ". Позволяет ли мне проверить этот вопрос другой механизм насмешек? ".

1 голос
/ 14 августа 2011

Спасибо @ckittel за указание на этот ответ. Чтобы это работало, класс Creature должен иметь конструктор без параметров, а методы должны быть виртуальными.

Еще одна особенность FakeItEasy, по-видимому, заключается в том, что вы должны указать ему вызывать базовый метод, иначе концептуально это тот же самый, просто другой синтаксис.

[Test]
public void Attack_TargetWith3Damage_CausesAttackerToDeal3DamageToTarget()
{
    var attacker = A.Fake<Creature>();
    A.CallTo(attacker).CallsBaseMethod(); //Otherwise it seems all calls are no-ops.
    attacker.Stats.Damage = 3;

    var target = A.Fake<ICreature>();
    attacker.Attack(target);
    A.CallTo(() => attacker.DealDamage(target, 3)).MustHaveHappened();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...