Как проверить, приводит ли возникновение события к методу, вызываемому условно по значению параметров - PullRequest
0 голосов
/ 29 марта 2010

Я пытаюсь написать модульный тест, который вызовет событие для фиктивного объекта, с которым связан мой тестовый класс.

Что я хочу проверить, так это то, что когда мой тестовый класс вызывает свой обработчик событий, он должен вызывать метод только для определенных значений параметров обработчика событий.

Мой тест, похоже, прошел, даже если я прокомментировал код, который вызывает ProcessPriceUpdate (price);

Я в VS2005, поэтому не надо лямбд, пожалуйста: (

Итак ...

public delegate void PriceUpdateEventHandler(decimal price);

public interface IPriceInterface{
    event PriceUpdateEventHandler PriceUpdate;
}

public class TestClass
{
    IPriceInterface priceInterface = null;

    TestClass(IPriceInterface priceInterface)
    {
        this.priceInterface = priceInterface;
    }

    public void Init()
    {
        priceInterface.PriceUpdate += OnPriceUpdate;
    }

    public void OnPriceUpdate(decimal price)
    {
        if(price > 0)
           ProcessPriceUpdate(price);
        }

    public void ProcessPriceUpdate(decimal price)
    {
        //do something with price
    }
}

И мой тест пока ...: s

public void PriceUpdateEvent()
    {
        MockRepository mock = new MockRepository();
        IPriceInterface pi = mock.DynamicMock<IPriceInterface>();
        TestClass test = new TestClass(pi);

        decimal prc = 1M;

        IEventRaiser raiser;

        using (mock.Record())
        {
            pi.PriceUpdate += null;

            raiser = LastCall.IgnoreArguments().GetEventRaiser();

            Expect.Call(delegate { test.ProcessPriceUpdate(prc); }).Repeat.Once();

        }
        using (mock.Playback())
        {
            test.Init();
            raiser.Raise(prc);
        }
    }

1 Ответ

0 голосов
/ 30 марта 2010

Обычно я разбиваю подобные вещи как минимум на два теста. Первый проверяет, что запуск события вызывает соответствующий обратный вызов (и этот обратный вызов вызывается ВСЕГДА, никаких условий). Условная логика, которую вы пытались проверить, переходит в соответствующий обратный вызов, который проверяется дополнительными отдельными тестами.

Первый тест можно реализовать путем создания производного класса из тестируемого класса с соответствующим переопределением обратного вызова, чтобы просто записать, что он был успешно вызван. Затем, когда вы запускаете событие, вы можете убедиться, что обратный вызов вызван.

Следующим шагом является непосредственное тестирование метода обратного вызова, как и любого другого метода.

Вот скелетный тест с кодом проверки, который вам понадобится для первого теста. Обратите внимание, что OnPriceUpdate станет виртуальным в TestClass:

public class TestClass_verifiesCallback : TestClass
{
    public bool WasCallbackCalled = false;
    public decimal PricePassedToCallback = 0;

    public override void OnPriceUpdate(decimal price)
    {
        WasCallbackCalled = true;
        pricePassedToCallback = price;
    }
}

... test methods

public TestInitSetsPriceUpdateCallback()
{
   .. setup

   var sut = new TestClass_verifiesCallback()

   .. run test

   // verification:
   Assert.IsTrue(sut.WasCallbackCalled);
   Assert.AreEqual(expectedValue, sut.PricePassedToCallback);
}

Ваши последующие тесты могут тестировать OnPriceUpdate напрямую.

...