Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试事件是否已订阅的扩展方法_C#_Unit Testing_Extension Methods_System.reflection_Microsoft Fakes - Fatal编程技术网

C# 单元测试事件是否已订阅的扩展方法

C# 单元测试事件是否已订阅的扩展方法,c#,unit-testing,extension-methods,system.reflection,microsoft-fakes,C#,Unit Testing,Extension Methods,System.reflection,Microsoft Fakes,我正在使用C#和Microsoft Fakes编写单元测试。我要测试的类订阅了服务中定义的大量事件。服务引用是私有的。Fakes已生成服务类接口的存根。我正在尝试为存根编写一个扩展方法,该方法将允许我确定我通过名称标识的事件是否有订户 我已经搜索并找到了一些例子,但没有一个具体适用于我正在做和不工作的事情。我想是因为存根 例如,此代码是从另一个StackOverflow post借用的,但不起作用,因为它未按名称找到任何事件: var rsEvent=relayService.GetType()

我正在使用C#和Microsoft Fakes编写单元测试。我要测试的类订阅了服务中定义的大量事件。服务引用是私有的。Fakes已生成服务类接口的存根。我正在尝试为存根编写一个扩展方法,该方法将允许我确定我通过名称标识的事件是否有订户

我已经搜索并找到了一些例子,但没有一个具体适用于我正在做和不工作的事情。我想是因为存根

例如,此代码是从另一个StackOverflow post借用的,但不起作用,因为它未按名称找到任何事件:

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

部分原因是因为Fakes将事件附加到名称,但即使我将“Event”附加到名称
GetEvent()
中,仍然无法识别该事件。我可以检索它的唯一方法是使用
GetMember()
。好啊这很好,但是如何将MemberInfo对象转换为
Action
事件,以便确定该事件是否已订阅?还是有更好的办法?我只想知道命名事件是否有订户

public interface IRelayService
{
    ...
    event Action<string> DisplayHandoffConversationTextEvent;
    ...
}
在扩展方法中,如何确定事件是否有订阅服务器?我被难住了


TIA

如果这不是异端邪说,下面是我如何获得扩展方法来实现我想要的:

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

在类中编写只在单元测试中使用的代码是一种代码味道,这很公平。那么,如何测试属于私有对象的事件是否接收到订阅者呢?记住,订阅事件的方法也是私有的。您通常不会对私有方法进行单元测试。您可以使用公共方法测试副作用。在这方面有很多不好的方法,其中一些已经讨论过了,但是这些方法只适用于不能重构为更好的体系结构的遗留代码。确保您理解SOLID,并在需要时尝试重构。我一直在考虑这个问题,并与另一位经验丰富的开发人员交谈。我们都不相信这是一种代码味道,因为我正在单元测试项目中扩展存根类。扩展方法不适用于生产代码。公平地说,我不知道这只是在您的测试解决方案中扩展的。我会问经验丰富的开发人员,他对单元测试私有方法有什么想法。
[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;
    }
}
    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;
        }
    }