AutoFixture + NSubstitute throws a NotASubstituteException for the entered car market

I get the following exception:

NSubstitute.Exceptions.NotASubstituteException: NSubstitute extension methods, such as .Received (), can only be called on objects created using Substitute.For () and related methods.

... when calling chargeService.When ():

public class WhenUserTopsUpAndStripeRejectsPaymentRequest
{
    [Theory, AutoNSubstituteData]
    public void it_should_throw_AutoTopUpFailedException(
        [Frozen] StripeChargeService chargeService,
        [Frozen] IRepository repository,
        TopUpUserAccountBalance message,
        TopUpUserAccountBalanceHandler sut) <== has dependency on StripeChargeService
    {
        repository.Find(Arg.Any<ById<User>>())
            .Returns(new User
            {
                AutoTopUpEnabled = true,
                AccountBalance = -15
            });

=====>  chargeService.When(s => s.Create(Arg.Any<StripeChargeCreateOptions>()))
            .DoNotCallBase();

        Assert.Throws<AutoTopUpFailedException>(() => sut.Handle(message));
    }
}

Now, of course, I can get around this by doing as Exception suggests, and manually create the StripeChargeService, and then manually create and inject all my dependencies into my SUT, but I would prefer to have less code and let AutoFixture do the work.

public class AndStripeRejectsPaymentRequest
{
    [Theory, AutoNSubstituteData]
    public void it_should_throw_AutoTopUpFailedException(
        IMediator mediator,
        IBillingConfig config,
        [Frozen] IRepository repository,
        TopUpDriverAccountBalance message)
    {
        var chargeService = Substitute.ForPartsOf<StripeChargeService>("");

        repository.Find(Arg.Any<ById<Driver, TopUpDriverAccountBalanceHandler.DriverProjection>>())
            .Returns(new TopUpDriverAccountBalanceHandler.DriverProjection
            {
                AutoTopUpEnabled = true,
                AccountBalance = -15
            });

        chargeService.When(s => s.Create(Arg.Any<StripeChargeCreateOptions>()))
            .DoNotCallBase();

        // Manually build SUT, with params declared above.
        var sut = new TopUpDriverAccountBalanceHandler(mediator, repository, config, chargeService);

        Assert.Throws<AutoTopUpFailedException>(() => sut.Handle(message));
    }
}

I thought that using AutoNSubstituteCustomization()the NuGet AutoFixture.AutoNSubstitute package automatically creates parameters with the arrogant use of NSubstitute. What am I doing wrong?

+4
1

AutoNSubstituteCustomization . , [Ploeh.AutoFixture.AutoNSubstitute.SubstituteAttribute]:

  [Theory, AutoNSubstituteData]
  public void it_should_throw_AutoTopUpFailedException(
      [Substitute] StripeChargeService chargeService)
  // ...

, ( v3.47.3), , , [Frozen] (. issue).

StripeChargeService AutoNSubstituteDataAttribute ( customization ):

internal class AutoNSubstituteDataAttribute : AutoDataAttribute
{
  public AutoNSubstituteDataAttribute()
  {
    this.Fixture.Customize(new AutoNSubstituteCustomization());

    // Substitute an instance of the 'StripeChargeService' type
    this.Fixture.Customizations.Insert(
      0,
      new FilteringSpecimenBuilder(
        new MethodInvoker(new NSubstituteMethodQuery()),
        new ExactTypeSpecification(typeof(StripeChargeService))));
  }
}
+4

All Articles