-
Notifications
You must be signed in to change notification settings - Fork 388
Use stripe-mock for tests #452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6d8e83e to
8a99660
Compare
23bf49e to
1b5b5cc
Compare
28c06da to
73591ed
Compare
|
I've updated the PR to add the ability to verify requests, and also stub requests (see the functional test for I think we have a good base to start porting all tests to stripe-mock. To summarize, for each model class, we want:
If we want to be exhaustive, we should also have deserialization tests for collection classes. @brandur-stripe @remi-stripe Any thoughts or questions? Anything I missed before we start porting all tests? |
73591ed to
651e536
Compare
Yep, that sounds absolutely perfect. I love that it'll get us a pretty exhaustive test of all possible expansions in a pretty direct way too.
IMO, it'd be fine just to make sure that this works for just one collection, but it's up to you :)
Just that this is going to be a monstrous amount of work :) The existing diff looks great. |
f91f035 to
ffc949a
Compare
f77cd7f to
d43b790
Compare
| import com.stripe.net.APIResource; | ||
| import com.stripe.model.*; | ||
| import junit.framework.Assert; | ||
| import org.junit.Test; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of a nit, but at some point in the future I'd like to enforce Google's Java style in the project. Can you reorder the import like in the other tests?
- All static imports first
- All imports in aphabetical order
- Separate import "groups" with a new line (in most cases the groups will be java, junit, then stripe)
- Don't use
.*, explicitly import all the classes you need.
| accountParams.put("limit", 3); | ||
| AccountCollection accountCollection = Account.all(accountParams); | ||
| @Test | ||
| public void testAccountUpdate() throws StripeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to testUpdate()
| } | ||
|
|
||
| @Test | ||
| public void testAccountReject() throws StripeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to testReject()
| import org.junit.Test; | ||
|
|
||
| import static org.junit.Assert.assertEquals; | ||
| import static org.mockito.Mockito.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about imports as above.
| @Test | ||
| public void testDeserialize() throws StripeException, IOException { | ||
| String json = getResourceAsString("account.json"); | ||
| String json = getResourceAsString("/api_fixtures/account.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than deserializing from an embedded JSON fixture, I'd rather we use stripe-mock whenever possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree partially because stripe-mock return non Custom accounts which won't deserialize a lot of the more complex sub-elements like legal_entity and external_accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to do both but that deserialization via stripe-mock happens in most of the other tests since we retrieve an account before reject/update/etc.
| Account acc = APIResource.GSON.fromJson(json, Account.class); | ||
|
|
||
| assertEquals("acct_1032D82eZvKYlo2C", acc.getId()); | ||
| assertEquals("acct_1234", acc.getId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary to check the value of every field (especially if you're using stripe-mock instead of an embedded fixture file). Mostly what we're testing here is that fromJson does not raise an exception.
In the other deserialization tests, I used just two asserts: assertNotNull(resource) + assertNotNul(resource.getId()) to check for the unlikely case where deserialization would not raise an exception but return null, or return an instance with null values in attributes.
For models with submodels (e.g. AccountPayoutSchedule), we should create a separate deserialization test for the submodel, e.g. in model/AccountPayoutScheduleTest.java:
String accountData = getFixture("/v1/accounts/acct_123");
String data = getDataAt(accountData, "payout_schedule");
AccountPayoutSchedule object = APIResource.GSON.fromJson(data, AccountPayoutSchedule.class);
assertNotNull(object);
assertNotNull(object.getInterval());(cf. ChargeOutcomeTest.java in the first commit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems pretty painful to maintain for the Account resource and all its sub-resources and various versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are separate classes in the code, so they should be tested separately. It will certainly be a bit painful to cover all models (mostly due to the fact that our coverage is pretty spotty right now), but once that's done, maintenance should be minimal.
4319402 to
59fbce5
Compare
|
@ob-stripe PTAL. I addressed all your comments (I think) and changed the Account model tests to only use stripe-mock's fixture. Then I moved LegalEntityTest to the new framework |
|
👍 Nice, looks great! Thanks for also deleting the old fixtures that are no longer used after you updated the tests. |
7be7bcb to
c0bda66
Compare
|
Okay, I think this is ~ready. Coverage numbers are still fairly low primarily because of the large number of untested deprecated methods (I've tried configuring the Cobertura plugin to ignore those, but it doesn't seem to be working too well) and some setter methods (which should also be excluded from coverage but I haven't looked into it yet). Note that there is one non-test change in this PR: I added a new method |
remi-stripe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of nitpicky/minor comments.
Also did we make sure to clean up all old fixtures and only have used ones in the new folder?
| public static final String UPLOAD_API_BASE = "https://uploads.stripe.com"; | ||
| public static final String LIVE_API_BASE = "https://api.stripe.com"; | ||
| public static final String CONNECT_API_BASE = "https://connect.stripe.com"; | ||
| public static final String UPLOAD_API_BASE = "https://files.stripe.com"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is safe right? I still have not fully understand the switch between files/uploads so wanted to flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, both files.stripe.com and uploads.stripe.com point to the same IP.
| ); | ||
| } | ||
|
|
||
| // TODO: Decide if sub-resources tests should live here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flagging that we should decide on that TODO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I kind of decided that already by adding CardTest and BankAccountTest, though currently they only test the customer sources case. We can add a few more tests specifically for instanceURL though.
| assertNotNull(resources); | ||
| verifyRequest( | ||
| APIResource.RequestMethod.GET, | ||
| String.format("/v1/application_fees") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we verify that params are passed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine to only verify params when there are params. Otherwise, we'd need to initialize and pass an empty map which is a bit annoying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but there are params here right?
| assertNotNull(resources); | ||
| verifyRequest( | ||
| APIResource.RequestMethod.GET, | ||
| String.format("/v1/balance/history") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we verify that params are sent? (won't repeat it for all retrieve, might be worth fixing all)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above, we are explicitly passing limit but not verifying it.
|
|
||
| @Test | ||
| public void testRetrieve() throws StripeException { | ||
| final Customer customer = Customer.retrieve(CUSTOMER_ID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have final here and not on any of the other examples? Should we fix them all? (annoying I know but consistency is king)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Immutability is good, so ideally all variables that can be declared as final should be. I think there's a linter rule that require that variables whose declaration is more than X lines away from their first use be declared as final, which is what prompted me to start using it in some places, and then thought that we might as well use it everywhere.
In practice, I don't think it's worth stressing about too much.
| @@ -0,0 +1,10 @@ | |||
| { | |||
| "id": "file_1BrE64KCFFPkgtRhvXK81rmT", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
random but let's not put a real id!
| @@ -0,0 +1,26 @@ | |||
| { | |||
| "id": "card_1CaO622eZvKYlo2C22sr7okI", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
card_123
| "object": "list", | ||
| "data": [ | ||
| { | ||
| "id": "file_1BrE64KCFFPkgtRhvXK81rmT", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file_123
| @@ -0,0 +1,37 @@ | |||
| { | |||
| "id": "src_1BoJ2NKrZ43eBVAb7Qj7bnQL", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src_123
| "routing_number": "110000000", | ||
| "swift_code": "TSTEZ122" | ||
| }, | ||
| "client_secret": "src_client_secret_CCiTVxSUWh1dzjv2qPyYuz55", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src_..._123
7794837 to
bf3f769
Compare
|
Can you maybe kick this back to me once Remi's feedback is satisfied and I'll give it one more pass over? Just looking at the general structure, I suspect that I won't have many qualms — the broad strokes all look totally right. I'm sure we'll find more to fix, but we can easily offload that to other PRs. This one is likely to become stale quickly. |
1400a37 to
e7859ad
Compare
|
Alright, I probably missed more than a few things, but:
ptal @remi-stripe |
| @Test | ||
| public void testConnectTimeout() throws IOException, StripeException { | ||
| // Kind of terrible, but let's test connection timeouts with a random external IP. | ||
| Stripe.overrideApiBase("https://254.254.254.254"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, what have I done 😱
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, actually, this wasn't a great idea (and also kind of rude to whoever owns this IP). I changed it to api.stripe.com. Hopefully Travis' servers are more than 1 millisecond away from Stripe's 😐
|
Thank you for going through all the changes thoroughly. Will defer to brandur on the second review. |
Co-authored-by: Rémi Jannel <[email protected]> Co-authored-by: Olivier Bellone <[email protected]>
|
ptal @brandur-stripe |
| } | ||
|
|
||
| Mockito | ||
| .doReturn(APIResource.GSON.fromJson(response, clazz)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this indentation right? Seems weird that the style is two spaces everywhere else, but then four spaces when chaining method calls like this.
|
Wow, WHAT A DIFF! Thanks for doing so much work. Okay, admittedly I only took a very high-level pass to see if I could spot anything untoward, but this LGTM. Very much looking forward to getting this in. ptal @ob-stripe |
Updated version of #384.