用于测试事件是否已订阅的扩展方法

时间:2019-04-24 17:44:26

标签: c# unit-testing extension-methods system.reflection microsoft-fakes

我正在使用C#和Microsoft Fakes编写单元测试。我要测试的类订阅了服务中定义的大量事件。服务参考是私有的。 Fakes生成了服务类的Interface的Stub。我正在尝试为存根编写一个扩展方法,该方法将使我能够确定由名称标识的事件是否具有订阅者。

我已经搜索并找到了一些示例,但是没有一个示例专门适用于我正在做的事情,但是不起作用。我认为是因为存根。

例如,此代码是从另一个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;
    }
}

在扩展方法中,如何确定事件是否有订阅者?我很困惑。

TIA

1 个答案:

答案 0 :(得分:0)

以防万一这不是异端,这就是我获得扩展方法以执行所需操作的方式:

    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;
        }
    }