我们正在使用machine.specifications.runner.resharper Reshaper扩展和MSpec 0.9.1.
[Subject(typeof(string))] internal class EstablishRunTwice { Establish sharedContext = () => Console.WriteLine("Shared context"); internal class ScenarioA : EstablishRunTwice { Establish scenarioAContext = () => Console.WriteLine("ScenarioA context"); internal class ScenarioAVariation1 : ScenarioA { Because of = () => Console.WriteLine("ScenarioAVariation1 Because"); It it1 = () => Console.WriteLine("ScenarioAVariation1 It1"); It it2 = () => Console.WriteLine("ScenarioAVariation1 It2"); } internal class ScenarioAVariation2 : ScenarioA { Because of = () => Console.WriteLine("ScenarioAVariation2 Because"); It it1 = () => Console.WriteLine("ScenarioAVariation2 It1"); It it2 = () => Console.WriteLine("ScenarioAVariation2 It2"); } } internal class ScenarioB : EstablishRunTwice { Establish context = () => Console.WriteLine("ScenarioB context"); Because of = () => Console.WriteLine("ScenarioB Because"); It it1 = () => Console.WriteLine("ScenarioB It1"); It it2 = () => Console.WriteLine("ScenarioB It2"); } }
结果是ScenarioAVariation1的结果:
Shared context Shared context ScenarioA context Shared context Shared context ScenarioA context ScenarioAVariation1 Because ScenarioAVariation1 It1 ScenarioAVariation1 It2
当我们使用NUnit进行自己的自定义上下文规范框架时,我们通过确保所有子类都是抽象的(在这种情况下,EstablishRunTwice和ScenarioA将是抽象的)来解决运行NUnit的问题,但MSpec在尝试这样做时抛出错误.
解决方法
所以让我看看,ScenarioA不仅嵌套在EstablishRunTwice中,而且还从它继承.这是否意味着它一直继承自身的嵌套副本到无穷大?然后,ScenarioB继承了所有这些!我的脑袋爆炸了.你得到令人困惑的结果我并不感到惊讶.嵌套真的给你什么?它是否使代码更易读或更易于维护?我不相信它确实如此.
使用KISS原则.正常的做法是将每个上下文放在自己的类中,不嵌套;只需使用文件对相关测试进行分组,您也可以使用[Subject]属性中的Concern参数作为另一种分组方式.如果有意义的话,你可以从其他上下文继承,但是在使用MSpec几年之后,我慢慢得出结论,过多的继承会损害可读性并使测试代码更加粘稠,所以明智地使用继承.
更新:反思我认为你想要实现的更长时间,我怀疑你正试图重新发明行为.这可能是MSpec的一个记录和理解不佳的特性,它允许您定义一组可以在以后在多个测试上下文中应用的常见行为.这听起来像你想要实现的那样吗?以下是行为的示例:
[Behaviors] internal class DenebRightAscension { It should_have_20_hours_ = () => UUT.degrees.ShouldEqual(20u); It should_have_41_minutes = () => UUT.Minutes.ShouldEqual(41u); It should_have_59_seconds = () => UUT.Seconds.ShouldEqual(59u); protected static bearing UUT; } [Subject(typeof(HourAngle),"sexagesimal")] internal class when_converting_hour_angle_to_sexagesimal { Because of = () => { RaDeneb = 20.6999491773451; UUT = new bearing(RaDeneb); }; Behaves_like<DenebRightAscension> deneb; protected static bearing UUT; static double RaDeneb; } [Subject(typeof(bearing),"sexagesimal")] internal class when_converting_to_sexagesimal { Because of = () => { RaDeneb = 20.6999491773451; UUT = new bearing(RaDeneb); }; Behaves_like<DenebRightAscension> deneb; protected static bearing UUT; static double RaDeneb; }
请注意,行为字段按名称匹配,而不是任何类型的继承.所以这种行为神奇地知道’UUT’的意思,即使这些类没有任何关系.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。