2009-08-27 2 views
4

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

ответ

0

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

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

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

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

0

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

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

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

2

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

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

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

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

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

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

+0

Это действительно идут мне думать о том, что вы говорите так Я отправил кое-что, что, надеюсь, является бесплатным для того, что вы сказали, ОЧЕНЬ хорошо для вызова этого друга, очень хорошо! –

0

Для примера 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, они его уволят.

Еще одна вещь, которая, вероятно, стоит отметить здесь, заключается в том, что вам, вероятно, не нужно будет реализовывать свои события совершенно так же, но руководство по программированию, выпущенное Microsoft, фактически вызывает условие гонки во второй части этого руководство TrueWill указывает. Вы можете найти это руководство here. Это на самом деле одно очень хорошее руководство от 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(); 
} 
Смежные вопросы