2014-01-21 7 views
2

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

Вот быстрый бит кода примера:

public class Sample 
{ 
    public delegate void OneParameterFunction(int someVar); 
    public event OneParameterFunction TheEvent;    

    public Sample() 
    {    
     TheEvent += CallMe; 
    } 

    public void CallMe(int someVar) 
    { 
     Debug.WriteLine("CallMe was fired with parameter: " + someVar); 
    } 

    public void FireEvent() 
    { 
     // do stuff, business logic here... 
     if (TheEvent != null) 
      TheEvent(3); 
    } 
} 

А вот тест я бы Любовь писать, но не может:

[TestClass] 
class EventMocking 
{ 
    [TestMethod] 
    public void DoNothingOnEvent() 
    { 
     var s = new Sample(); 

     Mock.Arrange(() => s.TheEvent(Arg.AnyInt))    
      .DoNothing(); 

     Mock.Arrange(() => s.CallMe(Arg.AnyInt)) 
      .OccursNever(); 

     s.FireEvent(); 

     Mock.Assert(() => s.CallMe(Arg.AnyInt)); 
    } 
} 

Но я получаю следующее сообщение об ошибке компилятора :

Error 1 The event 'Sample.TheEvent' can only appear on the left hand side of += or -= (except when used from within the type 'Sample') C:\BizObjectTests\EventMocking.cs 

Есть ли у кого-нибудь какие-либо предложения о том, как остановить распространение события? Я также не хочу Mock.Create<T> по ряду причин, один из которых я бы хотел, нужно настроить намного больше тестовых данных/объектов.

ответ

1

Невозможно высмеять вызов делегата, поскольку он реализован внутри JIT.

У вас есть несколько альтернативных вариантов. Если вы поднимаете событие в методе, предназначенном для этой цели (как в вашем примере), вы можете просто издеваться над этим методом. Таким образом, в вашем образце, который становится:

Mock.Arrange(() => s.FireEvent()).DoNothing(); 

Если это невозможно, то вы можете издеваться метод, который добавляет обработчики события (он вызывается, когда образец + = ... вызывается). Вы можете сделать это следующим образом:

var mock = Mock.Create<Sample>(); // we need this just for the following arrangement 
Mock.ArrangeSet(() => mock.TheEvent += null).IgnoreInstance().IgnoreArguments().DoNothing(); 

var real = new Sample(); // TheEvent += CallMe will now do nothing 
real.FireEvent(); // TheEvent is empty 

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

new PrivateAccessor(real).SetField("TheEvent", null); 
real.FireEvent(); // TheEvent is null right now 

РИСКОВАННЫЕ: этот последний вариант зависит от реализации компилятора. Он будет работать для объявлений событий в коде C#, но не будет работать для событий VB.

Смежные вопросы