3

NUnit 3.4.1、NSubstitute 1.10.0、NCrunch 2.23.0.2 を使用するテキスト フィクスチャがあります。

このフィクスチャには、いつでも 2 つの落下テストがあります。何かを変更するたびに、どのテストが失敗するかが異なるようです。すべてのテストが何度か失敗するわけではありませんが、ほとんどのテストは失敗し、問題は常に次のような行の NSubstitute 例外です。

// _clock is initialized as _clock = Substitute.For<IClock>();
// the dates in the Returns statement change on every test
_clock.Now.Returns(new DateTime(2015, 1, 1));

Resharper 2016 テスト ランナーではすべてのテストがパスするように見えるため、このミックスに NCrunch を追加します。多くの場合。

私が常に得る例外は次のとおりです。

NSubstitute.Exceptions.UnexpectedArgumentMatcherException : Argument matchers 
    (Arg.Is, Arg.Any) should only be used in place of member arguments. 
Do not use in a Returns() statement or anywhere else outside of a member call.

Arg.Isほとんどのテストでまたはを使用しないことを除いて、これは十分に明らかArg.Anyです。

IClock インターフェイス

IClockこれがすべての栄光のインターフェイスです。Nowは getter のみのプロパティですが、NSubstitute にとっては問題にならないはずです。

public interface IClock
{
    DateTime Now { get; }
}

完全なフィクスチャが近づいています

膨大な量のコードが表示されて申し訳ありませんが、それがいずれかのテストによるものだとは思いたくないので、次のようにします。

[TestFixture]
public class AuctionTests : TestBase
{
    #region Fields

    AuctionService _auctionService;
    IClock _clock;
    Ride _ride;
    IMailService _mailer;

    #endregion

    [SetUp]
    public void Init()
    {
        _clock = Substitute.For<IClock>();
        _mailer = Substitute.For<IMailService>();

        _ride = new Ride
        {
            StartAuction = new DateTime(2016, 2, 12, 19, 0, 23),
            PriceForCustomer = 20m,
            InitialAuctionPrice = 15m,
            HighestAuctionPrice = 19m
        };

        SetupData(_ride);

        _auctionService = new AuctionService(RavenSession, _clock, _mailer);
    }

    [Test]
    public void Auction_rejects_price_when_price_is_higher_then_HighestAuctionPrice()
    {
        const decimal price = 90m;
        _clock.Now.Returns(new DateTime(2015, 1, 1));

        var result = _auctionService.Accept(_ride.Id, price);

        result.Should().BeFalse();
    }

    [Test]
    public void Auction_rejects_price_when_inactive()
    {
        _clock.Now.Returns(new DateTime(2016, 2, 12, 20, 1, 23));

        var result = _auctionService.Accept(_ride.Id, Arg.Any<decimal>());

        result.Should().BeFalse();
    }

    [Test]
    public void Auction_is_inactive_when_current_time_is_before_auction_startDate()
    {
        _clock.Now.Returns(new DateTime(2016, 2, 12, 18, 0, 23));

        var result = _auctionService.Accept(_ride.Id, Arg.Any<decimal>());

        Assert.IsFalse(result);
    }

    [Test]
    public void Auction_is_active_when_current_time_is_exactly_auction_startDate()
    {
        _clock.Now.Returns(_ride.StartAuction);

        var result = _auctionService.Accept(_ride.Id, _ride.InitialAuctionPrice);

        result.Should().BeTrue();
    }

    [Test]
    public void Action_price_is_valid_at_auction_start_time_if_equal_to_initial_price()
    {
        var price = _ride.InitialAuctionPrice;

        _clock.Now.Returns(_ride.StartAuction);

        var result = _auctionService.Accept(_ride.Id, price);

        result.Should().BeTrue();
    }

    [Test]
    public void Action_price_is_valid_at_auction_end_time_if_equal_to_highest_possible_price()
    {
        var price = _ride.HighestAuctionPrice;

        _clock.Now.Returns(_ride.StartAuction.AddMinutes(60));

        var result = _auctionService.Accept(_ride.Id, price);

        result.Should().BeTrue();
    }

    [Test]
    public void Action_price_is_invalid_if_not_within_time_parameters()
    {
        var price = 12m;

        _clock.Now.Returns(_ride.StartAuction.AddMinutes(30));

        var result = _auctionService.Accept(_ride.Id, price);

        result.Should().BeFalse();
    }

    [Test]
    [Ignore("Uitzoeken hoeveel seconde vertraging wenselijk is")]
    public void Accept_takes_delay_in_requests_into_account()
    {
        var price = 17m;

        _clock.Now.Returns(_ride.StartAuction.AddMinutes(30).AddSeconds(30));

        var result = _auctionService.Accept(_ride.Id, price);

        result.Should().BeTrue();
    }

    [Test]
    public void Ride_is_saved_with_accepted_price()
    {
        var price = 17m;

        var date = _ride.StartAuction.AddMinutes(30);
        _clock.Now.Returns(date);

        var result = _auctionService.Accept(_ride.Id, price);

        Assert.IsTrue(result);

        var dbRide = RavenSession.Load<Ride>(_ride.Id);

        price.IsSameOrEqualTo(dbRide.AcceptedAuctionPrice);
    }

    [Test]
    public void On_Start_Auction_InitialAuctionPrice_should_be_fifteen_percent_of_PriceForCustomer()
    {
        _ride.PriceForCustomer = 100;

        _auctionService.StartAuction(_ride.Id);

        Assert.AreEqual(85m, _ride.InitialAuctionPrice);
    }

    [Test]
    public void On_Start_Auction_send_email_to_priorityPartners()
    {
        var priorityPartner = new Partner { Priority = true, Email = "some@email.com" };

        SetupData(priorityPartner, new Partner { Priority = false });

        _auctionService.StartAuction(_ride.Id);

        _mailer.Received(1).SendAuctionEmail(Arg.Any<string>(), _ride);
    }
}

私が見逃しているもの(明白な)はありますか?すべての準ランダム性は、すべてのテストでコードが適切に再初期化されていないことを示しているようですが、その方法が完全にわかりません。

どんな助けでも大歓迎です。

4

2 に答える 2

4

_auctionServiceこれらの行は、非置換 ( )で引数マッチャーを使用しようとしています。

var result = _auctionService.Accept(_ride.Id, Arg.Any<decimal>());

引数マッチャーは、 を介して作成された標準値ではなく、代替でのみ使用できますnew

于 2016-07-10T00:03:56.943 に答える