通过测试命令和事件的文档

时间:2012-05-03 13:10:35

标签: c# testing documentation cqrs event-sourcing

我愿意通过我的测试生成一些文档。到目前为止,我的测试看起来像这样:

 public class creation_of_a_new_inventory_item : BaseClass<CreateInventoryItem>
    {
    private Guid _Id = Guid.NewGuid();
    private string _Name = "test";

    public override CommandHandler<CreateInventoryItem> OnHandle(IRepository repository)
    {
        return  new CreateInventoryItemHandler(repository);
    }

    protected override IEnumerable<IEvent> Given()
    {
        yield break;
    }

    protected override CreateInventoryItem When()
    {
        return new CreateInventoryItem()
        {
            Id = _Id,
            Name = _Name
        };
    }

    protected override IEnumerable<IEvent> Expect()
    {
        yield return new InventoryItemCreatedAdded()
                         {
                             Id = _Id,
                             Name = _Name
                         };
    }

   [Test]
    public void does_not_throw_an_Exception()
    {
        Assert.IsNull(Caught);
    }
}

不幸的是,在使用Nunit时,我很难获得所需的信息,以便生成一些漂亮且易于阅读的文档。

你们有没有人使用Nunit这样做?你能给我一些有趣的资源,我会在网上忽略吗?您是否使用其他工具从测试中生成文档?

[编辑] 我的意图是在我的代码之外产生这样的东西:

 creation of a new inventory item
     When I Create Inventory Item 
        Id:{id},
        Name:{name}
     Then 
         Inventory Item is Created ({Success/Fail})
             Id:{id},
             Name:{name} 
     And does not throw an Exception ({Success/Fail})

这可以用于第一种方法。我可能会在以后改变一些事情,但主要目标是这样。我的目标是能够在不让他输入代码的情况下写出我老板可能理解的东西。

[/编辑]

2 个答案:

答案 0 :(得分:0)

我在Documently中得到了类似的东西:

[Subject(typeof(Customer))]
public class When_customer_relocates
    : Handler_and_Aggregate_spec
{
    static NewId AggregateId = NewId.Next();

    static RelocateTheCustomerHandler handler;

    Establish context = () =>
        {
            setup_repository_for<Customer>();
            has_seen_events<Customer>(CustomerTestFactory.Registered(AggregateId));
            handler = new RelocateTheCustomerHandler(() => repo);
        };

    Because of = () =>
        handler.Consume(a_command<RelocateTheCustomer>(new MsgImpl.Relocate
            {
                AggregateId = AggregateId,
                NewAddress = new MsgImpl.Address
                    {
                        City = "Berlin",
                        PostalCode = "4566",
                        Street = "FünfteStrasse",
                        StreetNumber = 45
                    },
                Version = 1U
            }));

    It should_have_loaded_existing = () =>
        A.CallTo(() => repo.GetById<Customer>(AggregateId, 1)).MustHaveHappened(Repeated.Exactly.Once);

    It should_have_published_relocated_event = () => 
        yieldedEvents.ShouldContain<Relocated>(
            r => r.City.ShouldEqual("Berlin"));

    Behaves_like<Event_versions_are_greater_than_zero> should_specify_versions_above_zero;
    Behaves_like<Event_versions_are_monotonically_increasing> should_specify_monotonically_increasing_versions;
    Behaves_like<Events_has_non_default_aggregate_root_id> should_have_non_default_ar_ids;
}

但是由你决定你发现它的可读性。

另一种选择可能是SpecFlow,如下所示:

Feature: Score Calculation 
  In order to know my performance
  As a player
  I want the system to calculate my total score

Scenario: Gutter game
  Given a new bowling game
  When all of my balls are landing in the gutter
  Then my total score should be 0

Scenario: Beginners game
  Given a new bowling game
  When I roll 2 and 7
  And I roll 3 and 4
  And I roll 8 times 1 and 1
  Then my total score should be 32

Scenario: Another beginners game
  Given a new bowling game
  When I roll the following series: 2,7,3,4,1,1,5,1,1,1,1,1,1,1,1,1,1,1,5,1
  Then my total score should be 40

Scenario: All Strikes
  Given a new bowling game
  When all of my rolls are strikes
  Then my total score should be 300

Scenario: One single spare
   Given a new bowling game 
   When I roll the following series: 2,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
   Then my total score should be 29

Scenario: All spares
  Given a new bowling game
  When I roll 10 times 1 and 9
  And I roll 1
  Then my total score should be 110

如果取决于你所谓的文件; spec flow实际上非常接近文档。

答案 1 :(得分:0)

不要打扰NUnit。只需使用反射扫描装配即可。测试夹具的结构总是相同的,因此生成文档非常容易。您还可以将描述()格式化方法的smth添加到所有命令和事件中,以获得具有实际值的描述性输出。