Jest имитирует метод базового класса ES6 (суперметод) при тестировании расширенного класса

У меня возникают проблемы при тестировании того, что исходный метод (из базового класса) вызывается с некоторыми параметрами при тестировании расширенного класса. Класс, который я хочу протестировать:

// ApiDataSource.js
import { RESTDataSource } from "apollo-datasource-rest";

export default class ApiDataSource extends RESTDataSource {
  constructor() {
    super();
    this.baseURL = 'test';
  }

  //We add the authorization params to the get method
  async get(path, params = {}, init = {}) {
    return super.get(
      path,
      {
        ...params,
        app_id: "test app id",
        app_key: "test app key",
      },
      init
    );
  }
}

И в основном, я хотел бы издеваться над super.get(), чтобы утверждать, что при вызове ApiDataSource.get() вызывается метод super с параметрами авторизации.

Что-то вроде:

// ApiDataSource.test.js
import ApiDataSource from './ApiDataSource'

// ...
test("adds the authorization parameters to the get call", async () => ({
  const class = new ApiDataSource();
  await class.get("test");

  expect(mockedSuperGet).toHaveBeenCalledWith("test", {app_id: "test app id", app_key: "test app key"})
});

Любая идея, как это сделать? пробовал jest.mock()jest.spyOn и так далее, и я не могу понять...

CodeSandbox: https://codesandbox.io/s/example-test-api-data-source-6ldpk?file=/src/ApiDataSource.test.ts

Конечно, просто издеваться/шпионить за RESTDataSource.prototype.get?

Bergi 21.12.2020 11:53

Не могли бы вы привести пример того, как это сделать @Bergi (на основе приведенного выше кода)?

Albert Alises 21.12.2020 11:56

У меня его нет под рукой, нет, но посмотрите их документацию. Не могли бы вы отредактировать свой вопрос, чтобы включить ваши попытки?

Bergi 21.12.2020 11:57

Быстро скомпилировали этот @Bergi: codeandbox.io/s/example-test-api-data-source-6ldpk?file=/sr‌​c/… кажется, что есть проблема с jest.mock(), но, возможно, вы поняли... также пытались издеваться над всем классом с помощью jest.mock("apollo-datasource-rest", () => ({ RESTDataSource: jest.fn()}) или чего-то еще, но тоже не добились успеха...

Albert Alises 21.12.2020 12:20

Вы не издеваетесь над суперклассом. Унаследованное поведение является частью поведения. Вместо этого издевайтесь над соавторами.

jonrsharpe 21.12.2020 12:35

Это интересно, Джонршарп. Как бы вы его проверили в этом случае?

Albert Alises 21.12.2020 12:53

Не существует единственно правильного подхода к этой проблеме. Здесь нет смысла издеваться над одним родительским методом, скорее, над всем родителем, особенно если он сторонний и производит побочные эффекты, такие как эта библиотека. Один из подходов состоит в том, чтобы не издеваться над родительским классом, а вместо этого использовать побочные эффекты, для этого тоже есть сторонние библиотеки, для этого, вероятно, github.com/NickTomlin/apollo-datasource-rest-testing. Вы можете дополнительно отслеживать внутренние вызовы, но только как способ более легкого отслеживания ошибок в собственном коде.

Estus Flask 21.12.2020 13:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
7
4 354
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать jest.spyOn(object, methodName), чтобы создать фиктивную функцию для RESTDataSource.prototype.get метода.

Например.

ApiDataSource.js:

import { RESTDataSource } from 'apollo-datasource-rest';

export default class ApiDataSource extends RESTDataSource {
  constructor() {
    super();
    this.baseURL = 'test';
  }

  async get(path, params = {}, init = {}) {
    return super.get(
      path,
      {
        ...params,
        app_id: 'test app id',
        app_key: 'test app key',
      },
      init
    );
  }
}

ApiDataSource.test.js:

import { RESTDataSource } from 'apollo-datasource-rest';
import ApiDataSource from './ApiDataSource';

describe('65391369', () => {
  test('adds the authorization parameters to the get call', async () => {
    const mockedSuperGet = jest.spyOn(RESTDataSource.prototype, 'get').mockResolvedValueOnce('fake data');
    const apiDataSource = new ApiDataSource();
    await apiDataSource.get('test');
    expect(mockedSuperGet).toHaveBeenCalledWith('test', { app_id: 'test app id', app_key: 'test app key' }, {});
    mockedSuperGet.mockRestore();
  });
});

результат модульного теста:

 PASS  examples/65391369/ApiDataSource.test.js (5.273 s)
  65391369
    ✓ adds the authorization parameters to the get call (4 ms)

------------------|---------|----------|---------|---------|-------------------
File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------------|---------|----------|---------|---------|-------------------
All files         |     100 |      100 |     100 |     100 |                   
 ApiDataSource.js |     100 |      100 |     100 |     100 |                   
------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.28 s

Некоторый комментарий о том, является ли это хорошей практикой, может быть полезен. То, что вы можете, не обязательно означает, что вы должны!

jonrsharpe 21.12.2020 12:47

Другие вопросы по теме