这个MSpec测试可以改进吗?

时间:2011-08-09 16:45:36

标签: bdd mspec

作为一名BDD和MSpec初学者,我仍然不太了解与BDD相关的最佳实践和良好习惯,特别是MSpec。

可以改进以下示例吗?它遵循最佳做法和良好习惯吗?

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

    [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);
        };
    }
    

1 个答案:

答案 0 :(得分: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,你可能会检查不属于规范或不相关的属性的相等性。

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