C# 单元测试事件是否已订阅的扩展方法
我正在使用C#和Microsoft Fakes编写单元测试。我要测试的类订阅了服务中定义的大量事件。服务引用是私有的。Fakes已生成服务类接口的存根。我正在尝试为存根编写一个扩展方法,该方法将允许我确定我通过名称标识的事件是否有订户 我已经搜索并找到了一些例子,但没有一个具体适用于我正在做和不工作的事情。我想是因为存根 例如,此代码是从另一个StackOverflow post借用的,但不起作用,因为它未按名称找到任何事件: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()
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;
}
}