Use when creating a fake test implementation in stripe-android — covers FakeClassName pattern, Turbine call tracking, ViewActionRecorder, and ensureAllEventsConsumed validation
npx skills add https://github.com/stripe/stripe-android --skill create-fake
This skill describes how to create fake implementations for testing in the Stripe Android SDK. The codebase strongly prefers fakes over mocks for better test reliability and clarity.
FakeClassName implementations that provide controllable, inspectable behaviorensureAllEventsConsumed() validation method when using Turbinessrc/test/java/com/stripe/android/.../FakeClassName.ktFake + interface/class name (e.g., FakeEventReporter, FakeCustomerRepository)internal to scope to the test moduleAlways use default parameters to make instantiation easy:
internal class FakeCustomerRepository(
private val paymentMethods: List<PaymentMethod> = emptyList(),
private val customer: Customer? = null
) : CustomerRepository {
// Implementation
}
For complex setup, provide a companion object factory method:
internal class FakePaymentMethodVerticalLayoutInteractor(
initialState: PaymentMethodVerticalLayoutInteractor.State,
initialShowsWalletsHeader: Boolean = false,
private val viewActionRecorder: ViewActionRecorder<PaymentMethodVerticalLayoutInteractor.ViewAction>
) : PaymentMethodVerticalLayoutInteractor {
companion object {
fun create(
paymentMethodMetadata: PaymentMethodMetadata = PaymentMethodMetadataFactory.create(),
initialShowsWalletsHeader: Boolean = true,
viewActionRecorder: ViewActionRecorder<PaymentMethodVerticalLayoutInteractor.ViewAction> = ViewActionRecorder()
): FakePaymentMethodVerticalLayoutInteractor {
// Complex initialization logic
val initialState = /* construct complex state */
return FakePaymentMethodVerticalLayoutInteractor(
initialState = initialState,
initialShowsWalletsHeader = initialShowsWalletsHeader,
viewActionRecorder = viewActionRecorder
)
}
}
}
Directly expose Turbines for test verification:
internal class FakeEventReporter : EventReporter {
val paymentFailureCalls = Turbine<PaymentFailureCall>()
val paymentSuccessCalls = Turbine<PaymentSuccessCall>()
override fun onPaymentFailure(error: Throwable, source: PaymentEventSource) {
paymentFailureCalls.add(PaymentFailureCall(error, source))
}
override fun onPaymentSuccess(paymentMethod: PaymentMethod) {
paymentSuccessCalls.add(PaymentSuccessCall(paymentMethod))
}
}
Define data classes to capture method call parameters:
data class PaymentFailureCall(val error: Throwable, val source: PaymentEventSource)
data class PaymentSuccessCall(val paymentMethod: PaymentMethod)
data class DetachRequest(val paymentMethodId: String, val customerId: String)
Implement a validation method that ensures all turbine events were consumed:
fun ensureAllEventsConsumed() {
paymentFailureCalls.ensureAllEventsConsumed()
paymentSuccessCalls.ensureAllEventsConsumed()
detachRequests.ensureAllEventsConsumed()
updateRequests.ensureAllEventsConsumed()
// ... validate all turbines
}
Tests should call this method after verification:
@Test
fun `test payment flow`() = runTest {
val fake = FakeEventReporter()
// Perform operations
fake.onPaymentSuccess(paymentMethod)
// Verify calls
assertThat(fake.paymentSuccessCalls.awaitItem()).isEqualTo(
PaymentSuccessCall(paymentMethod)
)
// Validate all events consumed
fake.ensureAllEventsConsumed()
}
For classes that handle view actions, use ViewActionRecorder:
internal class FakePaymentMethodVerticalLayoutInteractor(
initialState: PaymentMethodVerticalLayoutInteractor.State,
private val viewActionRecorder: ViewActionRecorder<PaymentMethodVerticalLayoutInteractor.ViewAction>
) : PaymentMethodVerticalLayoutInteractor {
override fun handleViewAction(viewAction: PaymentMethodVerticalLayoutInteractor.ViewAction) {
viewActionRecorder.record(viewAction)
// Optional: implement state changes based on action
}
}
Include ViewActionRecorder in factory with default:
companion object {
fun create(
paymentMethodMetadata: PaymentMethodMetadata = PaymentMethodMetadataFactory.create(),
viewActionRecorder: ViewActionRecorder<PaymentMethodVerticalLayoutInteractor.ViewAction> = ViewActionRecorder()
): FakePaymentMethodVerticalLayoutInteractor {
return FakePaymentMethodVerticalLayoutInteractor(
initialState = /* ... */,
viewActionRecorder = viewActionRecorder
)
}
}
Reference these fakes from the codebase as gold standards:
paymentsheet/src/test/java/com/stripe/android/paymentsheet/analytics/FakeEventReporter.kt
validate() method checking all turbinespaymentsheet/src/test/java/com/stripe/android/utils/FakeCustomerRepository.kt
paymentsheet/src/test/java/com/stripe/android/paymentsheet/verticalmode/FakePaymentMethodVerticalLayoutInteractor.kt
ensureAllEventsConsumed() that calls it on all Turbinescreate() factory methodExpert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.
> Wycheproof provides test vectors for validating cryptographic implementations. Use when testing crypto code for known attacks and edge cases.
Review fixed income portfolios by pricing multiple bonds, retrieving reference data, analyzing cashflows, and running scenario analysis. Use when reviewing bond portfolios, computing portfolio duration and DV01, analyzing cashflow waterfalls, stress testing rate scenarios, or assessing portfolio composition.
> based billing, idempotent webhooks, customer portal, dunning, and SCA. Use when building billing, handling webhooks, or testing with Stripe CLI.
Expert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.
Cointegration testing for pairs trading using Engle-Granger, Johansen, and rolling stability analysis
Apply systems thinking — causal loop diagrams, stock-and-flow models, system archetypes, and leverage-point analysis — to organizational, economic, or social problems where feedback loops, delays, or emergent behavior drive recurring failure across multiple interacting actors. Use this skill when the user describes a multi-actor situation that resists linear fixes: policy interventions that backfire, org-level fixes that break other teams, market symptoms that return after being solved, or time-lagged second-order consequences, even if they say 'why does fixing X make Y worse' or 'identify the leverage points in this system'. Do NOT use for single-cause software bugs, flaky tests, or regressions — those are debugging problems, not systems-thinking problems, even when phrased as 'this keeps coming back'.
Payment gateway testing including Stripe, PayPal, and Square integration testing with sandbox environments, webhook verification, and error handling.
Take stripe/create-fake from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.