Start learning free

LESSON 140 OF 173 · BACKEND: TESTS AND RUNNING IT

Fake the Other Service in TypeScript

Practice

When your shop calls another service, like a payment provider, your tests shouldn't call that service too. The real one may not be running, it charges real money, and you can't make it give the answer you want to test, like a declined card.

node:test gives every test function the running test, usually named t; TypeScript knows its type, so t needs none of its own. t.mock.method(object, "name", fake) swaps a function of a module for a fake called a mock, until the test ends. Whatever the fake returns is what the code gets back when it calls the function. Here a test fakes a shipping service on another route:

test("shipping price", async (t) => {
  t.mock.method(shipping, "quote", async () => {
    return { price: 5 };
  });
  const response = await client.get("/cart/shipping");
  assert.strictEqual(response.body.shipping, 5);
});

In this shop, paying an order calls payments.charge(amount, orderId) from the payments module, loaded at the top with require, like supertest. When the card is declined, the shop must answer 402 Payment Required, and the order must stay "pending". The check runs your tests on the shop and on two broken copies, then counts the calls that reached the real provider. When you're done, Run prints:

Your tests on the shop:
  new order is pending ... ok
  declined card ... ok
  2 tests: OK
Your tests on a copy that marks the order paid before it asks the provider:
  new order is pending ... ok
  declined card ... FAIL
    AssertionError: 'paid' != 'pending'
  2 tests: 1 failed, so they caught this bug
Your tests on a copy that ignores what the provider answers:
  new order is pending ... ok
  declined card ... FAIL
    AssertionError: 201 != 402
  2 tests: 1 failed, so they caught this bug
Calls to the real payment provider: 0

Your task: write the test "declined card". Mock payments.charge so it answers { error: "card_declined" }, pay order 1 with POST /orders/1/pay, check that the status is 402, then check that GET /orders/1 still shows the status "pending".


Assignment
Follow the Coding Tutorial to test a declined card, with a mock in place of the payment provider.


Hint
Set the mock before the POST, so payments.charge is the fake when the shop pays the order. Make the fake async, like the real charge. The checks come after the POST.


STEP 1 OF 7
    Ctrl + Enter to check

    Test Fake Service in TypeScript

    Keep going with TypeScript1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free