Метод расширения для модульного тестирования, подписаны ли события - PullRequest
1 голос
/ 24 апреля 2019

Я пишу модульные тесты, используя C # и Microsoft Fakes. Класс, который я хочу протестировать, подписывается на значительное количество событий, определенных в сервисе. Сервисная ссылка является частной. Fakes сгенерировал заглушку интерфейса класса обслуживания. Я пытаюсь написать метод расширения для заглушки, который позволит мне определить, имеет ли подписчик событие, которое я идентифицирую по имени.

Я искал и нашел несколько примеров, но ни один не относился конкретно к тому, что я делаю, и не работает. Я думаю из-за заглушки.

Например, этот код заимствован из другого поста StackOverflow, но не работает, потому что не находит ни одного события по имени:

var rsEvent = relayService.GetType().GetEvent(eventName + "Event", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

Частично причина в том, что Fakes добавляет Event к имени, но даже когда я добавляю «Event» к имени GetEvent(), он все равно не распознает событие. ЕДИНСТВЕННЫЙ способ, которым я могу получить это, используя GetMember(). ХОРОШО. Это здорово, но как мне преобразовать объект MemberInfo в событие Action<string>, чтобы я мог определить, было ли подписано событие? Или есть лучший способ? Все, что я хочу знать, есть ли у указанного события подписчик.

public interface IRelayService
{
    ...
    event Action<string> DisplayHandoffConversationTextEvent;
    ...
}
public class MainWindowViewModel : ViewModelBase
{
    ...
    private readonly IRelayService _relayService;
    ....
    public MainWindowViewModel()
    {
        ...
        _relayService = SimpleIoc.Default.GetInstance<IRelayService>();
        ...
    }

    public void InitializeServices() // method to be tested
    {
        ...
         _relayService.DisplayHandoffConversationTextEvent += OnDisplayHandoffConversationText;
        ...
    }
}
[TestClass]
public class MainWindowViewModelTests
{
    [ClassInitialize]
    public static void ClassInitialize(TestContext testContext)
    {
        ...
        _relayService = new StubIRelayService();
        ...
    }

    [TestMethod]
    public void InitializeServices_Test()
    {
        // Arrange
        var mwvm = new MainWindowViewModel();

         // Act
         mwvm.InitializeServices();

        // Assert

 Assert.IsTrue(_relayService.DoesEventHaveSubscriber("DisplayHandoffConversationTextEvent"));
            Assert.IsFalse(_relayService.DoesEventHaveSubscriber("AdminCanceledCallEvent"));
    }

}
public static class StubIRelayServiceExtensions
{
    public static bool DoesEventHaveSubscriber(this IRelayService relayService, string eventName)
    {
        var rsEvent = relayService.GetType().GetMember(eventName + "Event",
                BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
        if (rsEvent.Length > 0)
        {
            var member = rsEvent[0];
            // What do I do here?
            return true;
        }
        return false;
    }
}

Как определить, есть ли у подписчика событие в методе расширения? Я в тупике.

ТИА

1 Ответ

1 голос
/ 25 апреля 2019

На всякий случай, если это не ересь, вот как я получил метод расширения, чтобы делать то, что я хотел:

    public static class StubIRelayServiceExtensions
    {
        public static bool EventHasSubscriber(this IRelayService relayService, string eventName)
        {
            var eventField = relayService.GetType().GetField(eventName + "Event",
                BindingFlags.Public | BindingFlags.Instance);
            object object_value = eventField.GetValue(relayService);
            return object_value != null;
        }
    }
...