Поддельный запуск события из третьего класса - PullRequest
0 голосов
/ 19 июня 2011

Я пытаюсь написать тест взаимодействия, который должен запустить событие в классе, который мне не принадлежит (среда C # 4.0):

public class DoNotOwn
{
  public event EventHandler<SomeEventArgs> SomeEvent;
}

DoNotOwn не предоставляет защищенного OnSomeEvent для переопределения и не реализует никаких интерфейсов или каких-либо виртуальных членов. Тестируемый класс имеет экземпляр DoNotOwn и подписывается на SomeEvent:

public class ClassUnderTest
{
  private DoNotOwn x;

  public SetupDoNotOwn(DoNotOwn arg)
  {
    x = arg;
    x.SomeEvent += MyEventHandler;
  }

  protected void MyEventHandler(object sender, SomeEventArgs args)
  {
    // Does work that needs to be tested
  }
}

Мне известно, что я мог бы сделать отдельный метод доступным для теста, который выполняет внутренние функции MyEventHandler, но мне интересно, есть ли способ вызвать фиктивное событие DoNotOwn для запуска этого события.

У меня есть RhinoMocks, доступные в окружающей среде. Мои попытки вызвать это событие либо не приводят ни к какому событию, ни к жалобе «Неверный вызов, использовался последний вызов или не был сделан вызов (убедитесь, что вы вызываете виртуальный ... метод)», например с:

DoNotOwn stub = MockRepository.GenerateStub<DoNotOwn>();
stub.SomeEvent += null;
IEventRaiser eventer = LastCall.GetEventRaiser(); // InvalidOperationException

Я бы хотел попробовать Мок. Типок не в бюджете.

Ответы [ 3 ]

1 голос
/ 19 июня 2011

Проблема не в том, что у вас нет «protected OnSomeEvent». Обычно это имя для обработки события, а не срабатывания it.

Если вы не поняли ответ Криса, он говорит, что вы (поскольку у вас нет абстракции «IDoNotOwn» от DoNotOwn) вы можете вместо этого создать DoNotOwnWrapper, который реализует IDoNotOwnWrapper.

interface IDoNotOwnWrapper
{
    event EventHandler<SomeEventArgs> SomeEvent;
}

class DoNotOwnWrapper : IDoNotOwnWrapper
{
    DoNotOwn _internal;
    public DoNotOwnWrapper()
    {
         _internal = new DoNotOwn();
         _internal.SomeEvent += SomeEvent;
    } 
    event EventHandler<SomeEventArgs> SomeEvent;
}

Тогда вы можете легко зависеть от класса Wrapper и смоделировать его интерфейс Abstract в фреймворке.

Я бы определенно рекомендовал вам использовать Moq из-за его четкого синтаксиса, но RhinoMock и Moq справятся с задачей.

0 голосов
/ 19 июня 2011

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

public interface IClassDoNotOwn
{
    event EventHandler<SomeEventArgs> SomeEvent;
}

public class ExtendedDonNotOwn : ClassDoNotOwn, IClassDoNotOwn
{

}

И метод теста может быть:

    [Test]
    private void TestMethod()
    {
        var classDoNotOwn = MockRepository.GenerateStub<IClassDoNotOwn>();
        var classUnderTest = new ClassUnderTest();

        classDoNotOwn.Raise(dno=> dno.SomeEvent += null, this, EventArgs.Empty);
        ......
        ......

    }
0 голосов
/ 19 июня 2011

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

...