Search code examples
c#.netunit-testingstripe-paymentsxunit

How to unit test Stripe methods where they rely on a valid CustomerId to work


I'm quite new to testing.

I've got a really simple method that creates a Stripe user and attaches their Id to their User object in DB.

[Fact(DisplayName = "AddStripeCustomerIdAsync should save a StripeId to the User")]
public async Task Test_AddStripeCustomerIdAsync()
{
  // Arrange
  var customerCreateOptions = new CustomerCreateOptions
  {
     Email = "[email protected]"
  };
            
  // Act
  await _userCustomerService.AddStripeCustomerIdAsync(user, customerCreateOptions);
            
  // Assert
  Assert.False(user.StripeCustomerId.IsNullOrEmpty());
}

it works great. However a lot of other Stripe related tests rely on there being a valid Stripe Customer Id in the StripeCustomerId field. For example,

[Fact(DisplayName = "AddCardToAccount should add a reference for a card to the user.")]
public async Task Test_AddCardToAccount()
{
  // Act
  var result = paymentService.AddCardPaymentMethod(
                user, 
                "4242424242424242",
                9, 
                2025,
                "552");

  // Assert
  Assert.True(result);
}

This test fails, unless I hard code in a real Stripe customer Id to the user, or call the function that attaches a Stripe Id before running every test that uses it.

So currently I have

user = new ApplicationUser
{
  StripeCustomerId = "cus_ ..."
};

Which just feels WRONG. If that value is not a real Stripe customerId, Stripe exceptions are thrown everywhere. Am I doing okay and this is something that can't be helped, or am I missing something?


Solution

  • Solved it by creating a new Stripe customer with every test that needs a CustomerId. Just hope I don't get rate limited lol

    EDIT

    I was a foolish young developer at this time. My solution was to change my interface so that it doesn't return a Stripe object. I made a customer object that made mocking my Service using Stripe a lot easier.