3

作为 BDD 和 MSpec 初学者,我仍然不太确定与 BDD 相关的最佳实践和良好习惯,尤其是与 MSpec 相关的最佳实践。

下面的例子可以改进吗?它是否遵循最佳实践和良好习惯?

  1. 我的规范类和行为的命名是否正常?
  2. 我应该在这种情况下使用行为还是应该为规范类使用公共基类?
  3. 没有Establish这里可以吗?
  4. 我应该使用静态工厂方法(TestData方法)来获取测试数据还是应该在规范本身中创建数据?
  5. 而不是测试我可以使用的行为中的每个属性,result.Equals()但是我会测试两件事,这不好,对吧?

请随时将示例重构为您认为更好的示例。

[Subject(typeof(DataItemReader))]
public class When_reading_a_DataItem_from_stream
{
    Because of = () =>
    {
        using (var reader = new DataItemReader(
            new MemoryStream(TestData.GetNormalDataItemAsByteArray()), Encryption.None))
        {
            result = reader.ReadItem();
        }
    };

    Behaves_like<DataItemReader_that_reads_correctly> behavior;

    protected static DataItem result;
}

[Subject(typeof(DataItemReader))]
public class When_reading_a_DataItem_from_encrypted_stream
{
    Because of = () =>
    {
        using (var reader = new DataItemReader(
            new MemoryStream(TestData.GetNormalDataItemAsByteArrayEncyrpted()), Encryption.Default))
        {
            result = reader.ReadItem();
        }
    };

    Behaves_like<DataItemReader_that_reads_correctly> behavior;

    protected static DataItem result;
}

[Behaviors]
public class DataItemReader_that_reads_correctly
{
    protected static DataItem result;

    It should_read_the_correct_DataItem = () =>
    {
        var testItem = TestData.GetNormalDataItem();
        result.Property1.ShouldEqual(testItem.Property1);
        result.Property2.ShouldEqual(testItem.Property2);
        result.Property3.ShouldEqual(testItem.Property3);
    };
}
4

1 回答 1

6

世界对规范的看法可能更少,而更多的是您和您的团队/同行/“必须在您之后阅读此代码的人”可以从中获得什么。

从开发人员的角度来看:

  1. 我的大小写和命名遵循代码中可读的内容。HTML 提取的好处是您最终会获得可读的规范。我读过的很多内容都集中在所有小写字母之类的;然而,我的措辞和你的很像:适当的、可读的大小写。

  2. 对于像这样的一对一,行为对可读性非常有用。我使用基类来建立上下文并为重复的常见断言设置期望和行为。

  3. Establish一直意味着“在我的测试之前设置环境”。在您拥有的两个示例中,我可能会像这样重写它:

    Establish context = () => var reader = 
           new DataItemReader(new MemoryStream(     
           TestData.GetNormalDataItemAsByteArray()),                               
           Encryption.None));
    
    Because of = () => result = reader.ReadItem();
    
    Cleanup after = () => reader.Dispose();
    

    由于规范专注于“读取”的 DataItem,因此操作或Because就是这样。再次,偏好问题。

  4. 我使用可重用的静态工厂,我要么手工创建存根,要么拥有存根/模拟引擎(如 FakeItEasy http://code.google.com/p/fakeiteasy/)。在我看来,存根的内容/创建与实际测试几乎没有关系,应该被存根视为黑盒(这就是我们编写测试的原因,对吧?)。

  5. 我单独关注每个属性(如您所见),以确保它们符合我的期望。如果您曾经覆盖 Equals,您可能会检查不属于规范或不相关的属性的相等性。

我不确定是否有任何管理“最佳实践”(github 站点上有一些提示:https ://github.com/machine/machine.specifications#readme )。通过查看使用 MSpec 的其他项目并观察它们如何处理规范,我发现我的一些编码风格发生了变化。

于 2011-08-09T17:13:43.410 回答