Должен ли я тестировать обработчики событий - PullRequest
4 голосов
/ 27 августа 2009

Я склонен склоняться к мнению, что должны тестироваться только общедоступные интерфейсы, тем самым охватывая тестирование частных процедур. Однако вчера возник интересный вопрос - стоит ли тестировать обработчики событий? Мой инстинкт инстинкта заключается в том, что логика должна храниться в автономных процедурах, вызываемых самими обработчиками, но это субъективно и, скорее всего, приведет к частным процедурам, а не к публичным, которые тестируются. Должен ли я быть модульным тестером для обработки событий и, если да, каков наилучший метод для этого?

Ответы [ 4 ]

2 голосов
/ 27 августа 2009

Я ни в коем случае не скажу, что кто-то «не прав» для модульного тестирования обработчика событий. Лично я бы придерживался философии «проверь, что может сломаться», и не стал бы.

Главное, что я видел постоянно неправильно в коде события, это то, что модульные тесты не поймут - метод «Вкл» будет просто:

if (MyEventHandler != null)
    MyEventHandler(this, e);

Это состояние гонки; MyEventHandler должен быть назначен переменной перед проверкой нуля.

Вторая распространенная ошибка - люди, передающие значение null для параметра данных события «e»; это можно проверить.

Если у вас нет копии Руководства по проектированию инфраструктуры, 2-е изд. Cwalina & Abrams, купи это сейчас. Он расскажет вам, как правильно писать код события каждый раз, как правильно написать шаблон удаления и многое другое.

0 голосов
/ 05 октября 2012

К точке зрения TrueWill, вот пример хорошей реализации события и его метода повышения. Это событие Click класса Button от Microsoft. Сначала обратите внимание, что они используют EventHandlerList для хранения назначений в ...

protected EventHandlerList Events {
    get { 
        if (events == null) { 
            events = new EventHandlerList(this);
        } 
        return events;
    }
}

...

public event EventHandler Click {
    add {
        Events.AddHandler(EventClick, value); 
    }
    remove { 
        Events.RemoveHandler(EventClick, value); 
    }
} 

Теперь обратите внимание на фактический метод рейза OnClick, он, вероятно, сильно отличается от того, что вы привыкли видеть ...

protected virtual void OnClick(EventArgs e) { 
    Contract.Requires(e != null);
    EventHandler handler = (EventHandler)Events[EventClick]; 
    if (handler != null) handler(this, e); 
}

... не беспокойтесь о строке Contract.Requires(e != null);, это их инфраструктура управления контрактами, но обратите внимание, что она извлекает ее из EventHandlerList, а затем, если этот обработчик не null, они ее запустят. 1014 *

Еще одна вещь, которую, вероятно, стоит здесь отметить, это то, что вам, вероятно, не нужно будет реализовывать свои события совершенно таким же образом, но руководство по программированию, выпущенное Microsoft, фактически выявляет условия гонки во второй части этого руководства. что TrueWill указывает. Вы можете найти это руководство здесь . На самом деле это одно очень хорошее руководство от Microsoft.

Теперь, к вашей точке , я считаю, что события должны быть проверены, и вот механизм, который я использовал в прошлом ...

private ManualResetEvent _eventRaised = new ManualResetEvent(false);

[TestMethod]
public void TestSomething()
{
    _eventRaised.Reset();

    // hook up the event to the target being tested
    // NOW, in the event handler, issue _eventRaised.Set();

    // do something to raise the event

    _eventRaised.WaitOne();
}
0 голосов
/ 27 августа 2009

Я прочитал ваш вопрос и не знал, спрашивали ли вы о теле обработчика или действительно ли обработчик был связан правильно для обработки события.

Как вы говорите, тело обработчика должно просто вызвать другой метод, который вы уже тестировали (если он общедоступен).

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

0 голосов
/ 27 августа 2009

Я считаю, что обработчики событий должны быть проверены. Если вы следуете обычному порядку выполнения действий в соответствии с:

public event EventHandler MyEvent;
protected void OnMyEvent()
{
    // Raise MyEvent here
}

Тогда тестирование MyEvent фактически является частью теста OnMyEvent, поскольку единственный «тест», который вы будете выполнять, - это проверка правильности возникновения события.

Как правило, тестирование события означает подписку на него и выполнение чего-то, что должно (или не должно) вызывать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...