如何在xBehave测试中重用断言和/或设置?

时间:2016-12-21 14:44:31

标签: tdd bdd xunit.net xbehave.net

如果输入改变某些断言,但几乎所有其他断言保持不变,那么如何重新使用断言部分。在我的例子中,其中一个输入只会改变最后一个断言,其他所有断言都会保持不变。

    "When CreateBidCommand is executed"
        .x(() =>
        {
           _createBidCommand = new CreateBidCommand(_client, _bidYear, _optionNumber,
                _underwritingLicenseFiling, _underwriter, _bidType, _description, _claimsApplicationType);
            _commandDispatcher.Send(_createBidCommand);
        });
    "Then Bid should be created"
        .x(() =>
        {
            _bid = _bidRepository.FindByBidNumber(_client, _bidYear, _optionNumber);
            Assert.NotNull(_bid);
        });
    "  with description"
        .x(() => Assert.Equal(_bid.Description, _description));
    "  with Client"
        .x(() => Assert.Equal(_client.Id, _bid.Client.Id));
    "  with OptionNumber"
        .x(() => Assert.Equal(_bid.OptionNumber, _optionNumber));
    "  with BidType"
        .x(() => { Assert.Equal(_bid.BidType.Code, _bidType.Code); });
    "  with ClaimsApplicationType "
        .x(() => Assert.Equal(_bid.ClaimsApplicationType.Code, _claimsApplicationType.Code));
    "  with RegulatoryBody"
        .x(() => Assert.Equal(_bid.RegulatoryBody,_underwritingLicenseFiling.RegulatoryBody));
    "  with Underwriter"
        .x(() => Assert.Equal(_bid.Underwriter,  _underwriter));
    "  with UnderwritingFirm"
        .x(() => Assert.Equal(_bid.UnderwritingFirm,_underwritingLicenseFiling.UnderwritingFirm));
    "Then one and only one BidProposal should be created"
        .x(() => Assert.True(_bid.BidProposals().Count() == 1));
    "  with BaseForm"
        .x(() => Assert.Equal(_underwritingLicenseFiling.BaseForm, _bid.LatestProposal().BaseForm));
    "Then one and only one ClientPolicy should be created"
        .x(() =>
        {
            var clientPolicies = _clientPolicyRepository.FindByBidId(_bid.Id);
            Assert.Equal(clientPolicies.Count(), 1);
        });
    "Then ProductionSchedule should have only one step"
        .x(() => Assert.True(_bid.LatestProposal().ProductionSchedule.Count() == 1));
    "  and it should be Initial creation"
        .x(() =>
                Assert.True(_bid.LatestProposal().ProductionSchedule.ElementAt(0).BidStatusType.Code ==
                            BidStatusTypeCode.InitialCreation));

2 个答案:

答案 0 :(得分:0)

你的不同领域很难将这些字段浓缩成有意义和可读的东西。考虑引入一些可以用来匹配创建的出价的东西。您可以使用构建器模式轻松地创建所需的任何字段。例如:

// (Type declared here just to make it obvious)
FakeBid _expectedBid = new FakeBidBuilder().WithClient(_client)
                                   .WithBidYear(_bidYear)
                                   // etc.
                                   .Build();

使用构建器,您还可以轻松设置默认值,因此在这里只需要明显地设置特殊或有意义的数据。

当您调用该命令时,您现在可以从该虚假出价中传递参数:

_createBidCommand = new CreateBidCommand(
        _expectedBid.Client,
        _expectedBid.BidYear,
        // etc.
        );

现在你把匹配器放在FakeBid类上了:

AssertTrue(_expectedBid.Matches(_bid));

任何特殊检查都可以单独验证。

如果某些不同的出价匹配方式存在特殊情况,请与业务或代表进行对话,了解他们如何谈论出价及其含义,并了解您是否可以捕获不同构造函数和类名中的那种语言。

还要记住,如果您的出价创建的两个不同方面对两个不同的利益相关者有价值,那么它们可能应该分成不同的示例,因此更容易理解为什么它们就像它们一样。

使用像这样的类级别示例/测试的主要原因是不能捕获错误或测试代码;它可以强制执行干净的设计,并为其他任何人提供生活文档,并希望了解代码的作用以及代码的价值。希望这些模式能给你一些想法。

答案 1 :(得分:0)

我会通过创建一个为我做标准断言的测试DSL来做到这一点,例如

    "When CreateBidCommand is executed"
        .x(() =>
        {
           _createBidCommand = new CreateBidCommand(_client, _bidYear, _optionNumber,
                _underwritingLicenseFiling, _underwriter, _bidType, _description, _claimsApplicationType);
            _commandDispatcher.Send(_createBidCommand);
        });
    "Then Bid should be created"
        .x(() =>
        {
            _bid = _bidRepository.FindByBidNumber(_client, _bidYear, _optionNumber);
            Assert.NotNull(_bid);
        });
    "And the bid should have the properties descibed by the command"
        .x(() => AssertBid(_bid, _description, _client, ... ));
    ...

AssertBid是我测试DSL的方法。