Skip to main content

network-tests

Use when writing NetworkRule integration tests in stripe-android — covers testBodyFromFile, inline JSON modification, request matchers, and fixture patterns

Ir para a instalação

Informações da origem

Repositório
stripe/stripe-android
Última atividade na origem
4 de setembro de 2026 às 17:15
Idioma detectado do SKILL.md
inglês
Estrelas
1.537
Forks
736

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
network-tests
description
Use when writing NetworkRule integration tests in stripe-android — covers testBodyFromFile, inline JSON modification, request matchers, and fixture patterns
# NetworkRule Integration Tests For instrumentation tests that need mocked network responses, use `NetworkRule` (from `network-testing` module) with `testBodyFromFile`. JSON fixture files live in the module's `src/androidTest/resources/` directory (e.g., `paymentsheet/src/androidTest/resources/checkout-session-init.json`) and are resolved by filename from the resources root. ## Basic Structure ```kotlin @RunWith(AndroidJUnit4::class) internal class MyFeatureTest { @get:Rule val testRules: TestRules = TestRules.create() private val networkRule = testRules.networkRule @Test fun testSomething() = runPaymentSheetTest( networkRule = networkRule, resultCallback = ::assertCompleted, ) { testContext -> networkRule.enqueue(requestMatcher) { response -> response.testBodyFromFile("my-fixture.json") } // ... test actions ... } } ``` ## Prefer Inline JSON Modification Over New Fixture Files When a test needs a modified JSON response, use the `testBodyFromFile` lambda to modify the base fixture inline — do NOT create a separate JSON file for each variation. ```kotlin // GOOD: Modify the base fixture inline networkRule.checkoutInit { response -> response.testBodyFromFile("checkout-session-init.json") { json -> json.put("customer_email", "session@example.com") } } // BAD: Creating checkout-session-init-with-email.json with one field different networkRule.checkoutInit { response -> response.testBodyFromFile("checkout-session-init-with-email.json") } ``` This keeps the fixture set minimal and makes the test-specific modifications explicit at the call site. ## Composing Multiple Modifications The lambda receives a `JSONObject` — use standard `org.json` methods to add or modify fields: ```kotlin networkRule.checkoutInit { response -> response.testBodyFromFile("checkout-session-init.json") { json -> json.put("customer", JSONObject(""" { "id": "cus_12345", "payment_methods": [], "can_detach_payment_method": true } """.trimIndent())) json.put("customer_managed_saved_payment_methods_offer_save", JSONObject(""" {"enabled": true, "status": "not_accepted"} """.trimIndent())) } } ``` For nested modifications, chain `getJSONObject()`: ```kotlin response.testBodyFromFile("checkout-session-init.json") { json -> json.getJSONObject("server_built_elements_session_params") .getJSONObject("deferred_intent") .put("setup_future_usage", "off_session") } ``` ## Extracting Shared Modifiers When multiple tests share the same JSON modification, extract the lambda as a parameter: ```kotlin private fun runMyTest( jsonModifier: (JSONObject) -> Unit = {}, ) = runPaymentSheetTest(networkRule = networkRule, resultCallback = ::assertCompleted) { testContext -> networkRule.checkoutInit { response -> response.testBodyFromFile("checkout-session-init.json", jsonModifier) } // ... shared test logic ... } @Test fun testWithSfu() = runMyTest { json -> json.getJSONObject("server_built_elements_session_params") .getJSONObject("deferred_intent") .put("setup_future_usage", "off_session") } ``` ## testBodyFromFile Variants | Signature | Use when | |-----------|----------| | `testBodyFromFile("file.json")` | No modifications needed | | `testBodyFromFile("file.json") { json -> ... }` | Modifying JSON fields inline | | `testBodyFromFile("file.json", replacements)` | String-level find/replace with `ResponseReplacement` | ## Request Matchers Use `RequestMatchers` (from `com.stripe.android.networktesting.RequestMatchers`) to validate request body parameters. Import the matchers you need statically: ```kotlin import com.stripe.android.networktesting.RequestMatchers.bodyPart import com.stripe.android.networktesting.RequestMatchers.hasBodyPart import com.stripe.android.networktesting.RequestMatchers.not networkRule.checkoutConfirm( bodyPart("expected_amount", "5099"), not(hasBodyPart("save_payment_method")), ) { response -> response.testBodyFromFile("checkout-session-confirm.json") } ``` ## Enqueue Responses Next to Their Trigger Enqueue each response immediately before the operation that causes its request. Do not group responses for separate operations at the beginning of a test; doing so obscures which action needs each mock and makes request ordering harder to review. ```kotlin // Initial load request. networkRule.enqueue(consumerLookupMatcher) { response -> response.testBodyFromFile("consumer-session-lookup-success.json") } testContext.launch() // Requests triggered by confirmation and its subsequent refresh. networkRule.checkoutConfirm { response -> response.testBodyFromFile("checkout-session-confirm.json") } networkRule.checkoutInit { response -> response.testBodyFromFile("checkout-session-init.json") } page.clickConfirm() ``` When one user action triggers several requests asynchronously, enqueue all of those responses immediately before that action, keeping them in the same order as the expected requests. ### bodyPart Encoding `bodyPart()`, `hasBodyPart()`, and `query(name, value)` auto-decode both the matcher arguments and the request body before comparing. Use plain readable strings — `urlEncode()` is unnecessary: ```kotlin // Keys with brackets and values with special characters — just use plain strings bodyPart("billing_details[email]", "user@example.com") bodyPart("billing_details[address][line1]", "123 Main St") bodyPart("payment_method_data[allow_redisplay]", "unspecified") // urlEncode() still works (backward compatible) but is unnecessary // bodyPart(urlEncode("billing_details[email]"), urlEncode("user@example.com")) ``` ### Mismatch Debugging When a request doesn't match a mock, the error message shows per-matcher diagnostics with the nearest-miss mock: ``` POST https://localhost/v1/payment_intents/pi_123/confirm Body params: {billing_details[email]=actual@test.com, payment_method=pm_123} Nearest mock: composite(path(/v1/confirm), bodyPart(billing_details[email], expected@test.com)) + PASS: path(/v1/confirm) + PASS: method(POST) - FAIL: bodyPart(billing_details[email], expected@test.com) ``` See `PaymentSheetBillingConfigurationTest.kt` for more examples.
Ver no GitHub