这个MSpec测试可以改进吗?

bit*_*onk 3 bdd mspec

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

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

  1. 是我的规范类和行为的命名好吗?
  2. 我应该在这种情况下使用行为还是应该为spec类使用公共基类?
  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);
    };
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ker 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();
    
    Run Code Online (Sandbox Code Playgroud)

    由于规范侧重于"读取"的DataItem,因此操作或Because就是这样.同样,偏好问题.

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

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

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