在 Visual Studio 中测试私有成员





4.00/5 (1投票)
如何在 Visual Studio 中测试私有成员
我目前正在编写一个 CommandBehaviour
类,以便能够响应元素上任意路由事件触发命令,灵感来自 Sacha Barber 的文章:WPF: 附加命令。
在尝试对正在编写的代码进行单元测试时,我遇到了一个老生常谈的问题:如何测试那些设计为私有的内容。在正常情况下,我可能会将它们设为受保护,并在测试项目中编写一个继承自 CommandBehaviour
并暴露我想要测试的 protected
成员的 TestableCommandBehaviour
类。
然而,在这种特定情况下,我已经编写了代码,所以我使用了 Visual Studio 中的 创建单元测试 功能来为我生成一些单元测试,以便开始。我之前没有意识到的是,当你这样做时,它会创建一个“测试引用”,它为你提供一个 *私有访问器*,你可以使用它来访问 private
代码。
以下是 CommandBehaviour
类的一个简化版本
1: namespace DerekLakin.Libraries.Presentation
2: {
3: public class CommandBehaviour
4: {
5: public static readonly DependencyProperty CommandProperty =
6: DependencyProperty.RegisterAttached(
7: "Command",
8: typeof(ICommand),
9: typeof(CommandBehaviour),
10: new UIPropertyMetadata(null));
11:
12: public static readonly DependencyProperty CommandParameterProperty =
13: DependencyProperty.RegisterAttached(
14: "CommandParameter",
15: typeof(object),
16: typeof(CommandBehaviour),
17: new UIPropertyMetadata(null));
18:
19: public static readonly DependencyProperty EventNameProperty =
20: DependencyProperty.RegisterAttached(
21: "EventName",
22: typeof(string),
23: typeof(CommandBehaviour),
24: new UIPropertyMetadata(string.Empty,
new PropertyChangedCallback(EventNameChanged)));
25:
26: private static readonly DependencyProperty CommandBehaviourProperty =
27: DependencyProperty.RegisterAttached(
28: "CommandBehaviour",
29: typeof(CommandBehaviour),
30: typeof(CommandBehaviour),
31: new UIPropertyMetadata(null));
32:
33: private readonly WeakReference sourceElement;
34: private EventInfo eventInformation;
35: private Delegate targetDelegate;
36:
37: private CommandBehaviour()
38: {
39: }
40:
41: private CommandBehaviour(DependencyObject source)
42: {
43: this.sourceElement = new WeakReference(source);
44: }
45: ...
46: }
47: }
当设置 EventName
附加属性时会创建一个 CommandBehaviour
实例,并且当相关事件被挂钩时,targetDelegate
成员会被设置。在我的单元测试中,我想检查该成员是否真的被设置,以下是我使用访问器的方法
1: [TestMethod]
2: [DeploymentItem("DerekLakin.Libraries.Presentation.dll")]
3: public void RemoveEventHandlerTest()
4: {
5: Grid source = new Grid();
6: source.SetValue(
7: CommandBehaviour.CommandProperty,
8: ApplicationCommands.Open);
9: source.SetValue(
10: CommandBehaviour.EventNameProperty,
11: "MouseLeftButtonUp");
12: CommandBehaviour real = (CommandBehaviour)
13: source.GetValue(
14: CommandBehaviour_Accessor.CommandBehaviourProperty);
15: CommandBehaviour_Accessor target =
16: new CommandBehaviour_Accessor(
17: new PrivateObject(real));
18: Assert.IsNotNull(target.targetDelegate);
19: target.RemoveEventHandler();
20: Assert.IsNull(target.targetDelegate);
21: }
首先,我创建一个 Grid
实例,并在其上设置 Command
和 EventName
附加属性。接下来,我使用访问器的 CommandBehaviourProperty
(通常是 private
)从 Grid
实例中获取 CommandBehaviour
实例。然后,我创建一个使用 PrivateObject
类包装 CommandBehaviour
实例的 CommandBehaviour_Accessor
实例。最后,我使用常规的 Assert
语句来检查 private
成员。完成了!
* 有关测试 private
方法的更多信息,请参阅 MSDN 网站上的 如何:测试私有方法。