Open jeffplays2005 opened 6 months ago
@jeffplays2005 stripe.resources.Checkout
isn't like stripe.resources.Product
because checkout isn't a resource itself, it is a "namespace" that contains other resources like "checkout session".
Can you say a little bit about what you are hoping to accomplish? Using require('stripe')
directly isn't really part of the public interface of the library -- we usually expect users to stripe = require('stripe')("<API_KEY>")
and access things on the constructed stripe client, rather than interacting directly with the "building blocks" as you seem to be doing.
I'm trying to use this in jest for route testing for a route that has the method, stripe.checkout.sessions.list
.
I'm trying to change the function so that it can change the output of the data list.
E.g.
jest.mock("stripe", () => {
const stripe = jest.requireActual("stripe")
jest
.spyOn(stripe.resources.Checkout.sessions, "list")
.mockImplementation((props) => {
const { limit = 10 } = props as {
limit?: number
}
const items = Array(limit).fill(mock)
return Promise.resolve({ data: items })
})
})
@jeffplays2005 That still does not tell us why you were looking for any of the create/list/del etc. methods on stripe.resources.Checkout
...
What is the recommended way of mocking method calls? I'm trying to build a test in a similar fashion as @jeffplays2005, trying to spy on calls over checkout.sessions.create
, but it isn't easy when importing Stripe using ES module.
I cannot access instance methods before Stripe instance creation, but I read a thread on StackOverflow pointing out that hte created instance references methods in the resources, meaning I could stub those, but to no success
@amuroBosetti @jeffplays2005 Rather than mocking the method calls directly (which is possible, see below), you might first consider mocking the HTTP calls themselves using a tool like https://github.com/nock/nock. The API endpoints are well-defined and you can use the CLI to make some test requests and record their responses. That will allow the most flexibility without diving into the internal structure of the Stripe package (which is subject to change).
That said, the following toy example worked for me using TS and an ES Module:
// index.ts
import Stripe from "stripe";
const stripe = new Stripe("sk_test_...");
export const loadSessions = async () => {
const sessions = await stripe.checkout.sessions.create({
success_url: "https://example.com/passed-in-value",
mode: "setup",
currency: "usd",
payment_method_types: ["card"],
});
return sessions;
};
// index.test.ts
import { loadSessions } from ".";
jest.mock("stripe", () => {
return jest.fn().mockImplementation(() => {
return {
checkout: {
sessions: {
create: jest.fn().mockResolvedValue({
id: "cs_test_123",
object: "checkout.session",
billing_address_collection: "auto",
cancel_url: "https://example.com/cancel",
client_reference_id: null,
customer: null,
customer_email: null,
display_items: [
{
amount: 1000,
currency: "usd",
custom: {
description: "Pasha's Subscription",
images: null,
name: "Pasha's Subscription",
},
quantity: 1,
type: "custom",
},
],
livemode: false,
locale: null,
payment_intent: "pi_test_123",
payment_method_types: ["card"],
setup_intent: "seti_test_123",
submit_type: null,
subscription: null,
success_url: "https://example.com/mocked-value",
}),
},
},
};
});
});
it("should mock the whole stripe call", async () => {
const sessions = await loadSessions();
expect(sessions.success_url).toEqual("https://example.com/mocked-value");
});
Alternatively, you could wrap calls to stripe in helper methods and mock those directly:
// mock my loadSessions function:
jest.mock("./index", () => {
return {
loadSessions: jest.fn().mockResolvedValue({
id: "cs_test_123",
object: "checkout.session",
billing_address_collection: "auto",
success_url: "https://example.com/local-mock",
}),
};
});
it("should use a local mock", async () => {
const sessions = await loadSessions();
expect(sessions.success_url).toEqual("https://example.com/local-mock");
});
Though it's worth noting that you can't use those two approaches in the same file, since they'll conflict.
Will any of those 3 approaches work for you?
Describe the bug
Seems to be empty compared to other prototypes.
To Reproduce
Expected behavior
{ create: [Function (anonymous)], retrieve: [Function (anonymous)], list: [Function (anonymous)], expire: [Function (anonymous)], listLineItems: [Function (anonymous)] }
Code snippets
No response
OS
macOS
Node version
Node v20.0.0
Library version
14.23.0
API version
2022-08-01
Additional context
No response