Вы правы в том, что не можете получить доступ к делегатам событий извне класса, это ограничение в языке C #.
Самый простой подход для проверки этого состоит в том, чтобы имитировать класс B изатем поднять его событие и затем наблюдать побочные эффекты от события, которое поднимается.Это немного отличается от того, что вы ищете, но демонстрирует поведение класса A, а не его реализацию (это то, к чему должны стремиться ваши тесты).
Чтобы это работало, класс B должен бытьmockable и событие, которое оно выставляет, также должно быть виртуальным.Moq не может перехватывать события, если они не объявлены как виртуальные.В качестве альтернативы, если B является интерфейсом, убедитесь, что событие объявлено там.
public interface IEventProvider
{
event EventHandler OnEvent;
}
public class Example
{
public Example(IEventProvider e)
{
e.OnEvent += PerformWork;
}
private void PerformWork(object sender, EventArgs e)
{
// perform work
// event has an impact on this class that can be observed
// from the outside. this is just an example...
VisibleSideEffect = true;
}
public bool VisibleSideEffect
{
get; set;
}
}
[TestClass]
public class ExampleFixture
{
[TestMethod]
public void DemonstrateThatTheClassRespondsToEvents()
{
var eventProvider = new Mock<IEventProvider>().Object;
var subject = new Example(eventProvider.Object);
Mock.Get(eventProvider)
.Raise( e => e.OnEvent += null, EventArgs.Empty);
Assert.IsTrue( subject.VisibleSideEffect,
"the visible side effect of the event was not raised.");
}
}
Если вам действительно необходимо протестировать реализацию, существуют другие доступные механизмы, такие как рука-rolled Test Spy / Test Double , или основанная на отражении стратегия, чтобы получить список делегатов.Я надеюсь, что вы должны быть более озабочены логикой обработки событий класса А, чем его назначением обработчика событий.В конце концов, если класс А не отвечает на событие и что-то с ним делает, назначение не должно иметь значения.