当您说“它完成所有父级[功能]”时,我认为这两种类型实现了相同的接口,或者至少是继承的。您想使用 MSpec 的Behaves_like
功能。
“行为定义了封装一组特定行为的可重用规范,你猜对了,你可以在任何表现出特定行为的上下文中包含这些规范。” ——詹姆斯·格雷戈里
我不知道 RSS 数据源阅读器是如何工作的,所以让我向您展示一些我使用行为的示例代码。我需要将一些愚蠢的 API 中的 2 的整数幂(0、1、2、4 等)转换为 AZ 字符。所以,规格将是
It should_convert_0_to_A = () => _converter.Convert(0).ShouldEqual('A');
It should_convert_1_to_B = () => _converter.Convert(1).ShouldEqual('B');
// ... and so on ...
It should_convert_16777216_to_Z = () => _converter.Convert(16777216).ShouldEqual('Z');
但是,我有三种不同的接口实现。它们包括二进制转换、日志转换和查找表。
public interface IUnitMaskConverter
{
char Convert(uint mask);
}
我不会将 26 种规格复制三次或更多次!所以,我将规范设置为一个Behaviors
类
[Behaviors]
public class UnitMaskConverterBehaviors
{
It should_convert_0_to_A = () => _converter.Convert(0).ShouldEqual('A');
It should_convert_1_to_B = () => _converter.Convert(1).ShouldEqual('B');
// ... and so on ...
It should_convert_16777216_to_Z = () => _converter.Convert(16777216).ShouldEqual('Z');
protected static IUnitMaskConverter _converter;
}
因此,编写一个说明此实现的行为类似于“单位掩码转换器”的规范类非常容易
[Subject(typeof(IUnitMaskConverter))]
public class When_converting_unit_masks_by_lookup
{
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter;
protected static LookupUnitMaskConverter _converter = new LookupUnitMaskConverter();
}
[Subject(typeof(IUnitMaskConverter))]
public class When_converting_unit_masks_by_log
{
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter;
protected static LogUnitMaskConverter _converter = new LogUnitMaskConverter();
}
[Subject(typeof(IUnitMaskConverter))]
public class When_converting_unit_masks_by_binary
{
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter;
protected static BinaryUnitMaskConverter _converter = new BinaryUnitMaskConverter();
}
该报告甚至列出了每个实现的所有行为。
IUnitMaskConverter 规格
4 种上下文,108 种规格
通过二进制转换单位掩码时
26种规格
- 应该将 0 转换为 A
- 应该将 1 转换为 B
- ...
- 应将 16777216 转换为 Z
通过查找转换单位掩码时
26种规格
- 应该将 0 转换为 A
- 应该将 1 转换为 B
- ...
- 应将 16777216 转换为 Z