টাইপস্ক্রিপ্ট সহ ঠাট্টায় মক নির্ভরতা


94

কোনও মডিউল পরীক্ষা করতে যখন কোনও আলাদা ফাইলে নির্ভরতা রয়েছে। টাইপস্ক্রিপ্ট হিসাবে সেই মডিউলটি নির্ধারণের সময় jest.Mockএকটি ত্রুটি দেয় যে পদ্ধতিটি mockReturnThisOnce(বা অন্য কোনও ঠাট্টা। মক পদ্ধতি) নির্ভরতার উপর বিদ্যমান নেই, কারণ এটি আগে টাইপ করা হয়েছিল। Jest.Mock থেকে প্রকারের উত্তরাধিকারী হওয়ার জন্য টাইপস্ক্রিপ্ট পাওয়ার উপযুক্ত উপায় কী?

এখানে একটি দ্রুত উদাহরণ।

নির্ভরতা

const myDep = (name: string) => name;
export default myDep;

test.ts

import * as dep from '../depenendency';
jest.mock('../dependency');

it('should do what I need', () => {
  //this throws ts error
  // Property mockReturnValueOnce does not exist on type (name: string)....
  dep.default.mockReturnValueOnce('return')
}

আমি মনে করি এটি খুব সাধারণ ব্যবহারের ক্ষেত্রে এবং সঠিকভাবে এটি কীভাবে টাইপ করা যায় তা নিশ্চিত নয়। কোন সাহায্যের অনেক প্রশংসা হবে!


4
আমি যদি ঠিক মনে রাখি তবে আমদানির আগে আপনাকে বিদ্রূপ করতে হবে। কেবল প্রথম 2 লাইন স্যুইচ করুন। তবে আমি এ সম্পর্কে নিশ্চিত নই।
থমাস

4
@ ইএস K এর মাধ্যমে আমদানি করা টমাসক্লেন মডিউলগুলি importপ্রথমে মূল্যায়ন করা হয়, আপনি আমদানির আগে কিছু কোড রাখেন তা বিবেচনাধীন । সুতরাং এটি কাজ করবে না।
মিগ্রোল

@ থমাস jest.mock এ কলগুলি কোডের শীর্ষে উত্তোলন করা হয় - জাস্ট জাদু আমার ধারণা ... ( রেফ ) যাইহোক, এটি কিছু সমস্যা তৈরি করে, যেমন মডিউল কারখানার প্যারামিটারের সাথে jest.mock () কল করার সময় মক ফাংশনগুলির নাম দিন যেমনmock...
টোবি

উত্তর:


98

আপনি টাইপ কাস্টিং ব্যবহার করতে পারেন এবং আপনার test.tsদেখতে এটির মতো হওয়া উচিত:

import * as dep from '../dependency';
jest.mock('../dependency');

const mockedDependency = <jest.Mock<typeof dep.default>>dep.default;

it('should do what I need', () => {
  //this throws ts error
  // Property mockReturnValueOnce does not exist on type (name: string)....
  mockedDependency.mockReturnValueOnce('return');
});

টিএস ট্রান্সপোর্টার সচেতন নয় যে jest.mock('../dependency');প্রকারের পরিবর্তনের depফলে আপনাকে টাইপ কাস্টিং ব্যবহার করতে হবে। যেমন আমদানি depকোনও ধরণের সংজ্ঞা নয় তবে আপনাকে এর ধরণটি পেতে হবে typeof dep.default

জেস্ট এবং টিএস এর সাথে আমার কাজের সময় আমি খুঁজে পেয়েছি এমন আরও কিছু দরকারী নিদর্শন এখানে রয়েছে

যখন আমদানি করা উপাদানটি একটি শ্রেণি হয় তবে আপনাকে টাইপফোন ব্যবহার করতে হবে না উদাহরণস্বরূপ:

import { SomeClass } from './SomeClass';

jest.mock('./SomeClass');

const mockedClass = <jest.Mock<SomeClass>>SomeClass;

আপনি যখন কিছু নোড নেটিভ মডিউলগুলি উপহাস করতে হবে তখন এই সমাধানটিও কার্যকর is

import { existsSync } from 'fs';

jest.mock('fs');

const mockedExistsSync = <jest.Mock<typeof existsSync>>existsSync;

আপনি যদি জেস্ট স্বয়ংক্রিয় মক ব্যবহার করতে না চান এবং ম্যানুয়াল তৈরি করতে পছন্দ করেন না সে ক্ষেত্রে

import TestedClass from './TestedClass';
import TestedClassDependency from './TestedClassDependency';

const testedClassDependencyMock = jest.fn<TestedClassDependency>(() => ({
  // implementation
}));

it('Should throw an error when calling playSomethingCool', () => {
  const testedClass = new TestedClass(testedClassDependencyMock());
});

testedClassDependencyMock()বিদ্রূপযুক্ত বস্তুর উদাহরণটি TestedClassDependencyশ্রেণি বা প্রকার বা ইন্টারফেস হতে পারে creates


4
এর jest.fn(() =>...পরিবর্তে আমাকে ব্যবহার করতে হয়েছিল jest.fn<TestedClassDependency>(() =>...(আমি কেবল jest.fn এর পরে টাইপ কাস্টিংটি সরিয়ে ফেলেছি) কারণ ইন্টেলিজজে অভিযোগ করছে। নাহলে এই উত্তরটি আমাকে সাহায্য করেছে ধন্যবাদ! এটি আমার প্যাকেজ.জসনে ব্যবহার করে: "@ প্রকারগুলি / উপহাস": "^ 24.0.3"
এ। ম্যাসন

jest.mock('./SomeClass');উপরের কোডে কি আছে ?
রেজা

11
হাম এটি শেষ টিএস সংস্করণ এবং রসিকতা 24 :( সাথে আর কাজ করবে না
ভিনসেন্ট

4
@ রেজা এটি অটোর মক, জেস্টজেএস.আইও
ব্রুস লি

4
<jest.Mock<SomeClass>>SomeClass: অভিব্যক্তি আমার জন্য একটি হিজড়া ত্রুটি উত্পাদক হয়Conversion of type 'typeof SomeClass' to type 'Mock<SomeClass, any>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'typeof SomeClass' is missing the following properties from type 'Mock<SomeClass, any>': getMockName, mock, mockClear, mockReset, and 11 more.ts(2352)
the21st

61

এখানে বর্ণিত মত mockedথেকে সহায়কটি ব্যবহার করুনts-jest

// foo.spec.ts
import { mocked } from 'ts-jest/utils'
import { foo } from './foo'
jest.mock('./foo')

// here the whole foo var is mocked deeply
const mockedFoo = mocked(foo, true)

test('deep', () => {
  // there will be no TS error here, and you'll have completion in modern IDEs
  mockedFoo.a.b.c.hello('me')
  // same here
  expect(mockedFoo.a.b.c.hello.mock.calls).toHaveLength(1)
})

test('direct', () => {
  foo.name()
  // here only foo.name is mocked (or its methods if it's an object)
  expect(mocked(foo.name).mock.calls).toHaveLength(1)
})

এবং যদি

  • তুমি ব্যাবহার কর tslint
  • ts-jest আপনার দেব-নির্ভরতা মধ্যে আছে,

এই নিয়মটি আপনার যুক্ত করুন tslint.json:"no-implicit-dependencies": [true, "dev"]


এখানে ব্যবহার আরো কয়েকটি উদাহরণ দেওয়া হল ts-jest: এবং শ্রেণীর github.com/tbinna/ts-jest-mock-examples : এবং পোস্টটি stackoverflow.com/questions/58639737/...
টবি

4
এটি সর্বাধিক ভোট প্রাপ্ত একটির চেয়ে অনেক বেশি ভাল উত্তর।
নকল প্লাস্টিকঅ্যান্ড্রয়েড

রেপো তে @Tobi দ্য পরীক্ষা ব্যর্থ
Kreator

শীর্ষস্থানীয় @ ক্রেটারের জন্য ধন্যবাদ আপনি যে হিসাবে রিপোর্ট করেছেন একই সমস্যাটি দেখতে পাচ্ছেন ? আমি এখনও কোনও ইস্যু পুনরুত্পাদন করতে পারে না।
টবি

@ ক্রেটার সবেমাত্র একটি পিআর মার্জ করেছে। সমস্যাটি যদি অব্যাহত থাকে তবে আমাকে জানতে দিন
টবি

18

আমি @ প্রকারের / জেস্ট / ইনডেক্স.ডেটস থেকে প্যাটার্নটি মক্কের জন্য টাইপ ডিফের ঠিক উপরে (515 লাইন) ব্যবহার করি:

import { Api } from "../api";
jest.mock("../api");

const myApi: jest.Mocked<Api> = new Api() as any;
myApi.myApiMethod.mockImplementation(() => "test");

4
আমি নিশ্চিত যে আপনি ঠিক করতে পেরেছিলেনconst myApi = new Api() as jest.Mocked<Api>;
স্নোফ্রোগদেব

4
@ নিউফ্ল্যাশ: টাইপস্ক্রিপ্ট ৩.৪-তে কঠোর মোডে নেই - এটি অভিযোগ করবে যে এপি টাইপ যথেষ্ট পরিমাণে ওভারল্যাপ করে না jest.Mock<Api>। আপনার সাথে যেতে হবে const myApi = new Api() as any as jest.Mock<Api>এবং আমি বলতে চাই যে উপরের একটিটি ডাবল দৃ than়তার চেয়ে কিছুটা ভাল দেখাচ্ছে।
পলোস্টাইল

@ টুপটাস: 3.4 এর জন্য কড়া মোড টাটকা? এই সম্পর্কে আপনার একটি লিঙ্ক আছে দয়া করে?
এলমপ্পে

@ এমএমপি: আপনার অর্থ কী তা নিশ্চিত নয়। "কড়া মোড" বলতে আমার বোঝানো "strict": trueহয়েছে tsconfig.json এ। এই কভার ভালো জিনিস noImplicitAny, strictNullChecksইত্যাদি যাতে আপনি স্বতন্ত্রভাবে তাদের জন্য সত্যতে সেট করতে হবে না।
পলোস্টাইল

আমি পাই না। আপনি কেবলমাত্র একটি উদাহরণের পদ্ধতিটি কেন স্টিবিং করছেন myApi? এটি সাধারণভাবে Apiপরীক্ষা করা হচ্ছে মডিউলটির মধ্যে বর্গ দ্বারা শুরু করা সমস্ত অন্যান্য দৃষ্টিকোণকে ঝুঁকবে না ?
ইভান ওয়াং

14

দুটি সমাধান রয়েছে, উভয়ই পছন্দসই ফাংশন castালাই করছেন

1) jest.MockFunction ব্যবহার করুন

import * as dep from './dependency';

jest.mock('./dependency');

const mockMyFunction = dep.myFunction as jest.MockedFunction<typeof dep.myFunction>;

2) jest.Mock ব্যবহার করুন

import * as dep from './dependency';

jest.mock('./dependency');

const mockMyFunction = dep.default as jest.Mock;

এই দুটি সমাধানের মধ্যে কোনও পার্থক্য নেই। দ্বিতীয়টি সংক্ষিপ্ত এবং আমি তাই এটি ব্যবহার করার পরামর্শ দেব।

উভয় ingালাই সমাধানগুলি যেকোন জাস্ট মক ফাংশনটিকে mockMyFunctionলাইক mockReturnValueবা https://jestjs.io/docs/en/mock-function-api.html এ কল করতে দেয়mockResolvedValue

mockMyFunction.mockReturnValue('value');

mockMyFunction প্রত্যাশার জন্য সাধারণত ব্যবহার করা যেতে পারে

expect(mockMyFunction).toHaveBeenCalledTimes(1);


6

Jest@24.8.0 এবং ts-jest@24.0.2 দিয়ে আমি যা করেছি তা এখানে :

সূত্র:

class OAuth {

  static isLogIn() {
    // return true/false;
  }

  static getOAuthService() {
    // ...
  }
}

পরীক্ষা:

import { OAuth } from '../src/to/the/OAuth'

jest.mock('../src/utils/OAuth', () => ({
  OAuth: class {
    public static getOAuthService() {
      return {
        getAuthorizationUrl() {
          return '';
        }
      };
    }
  }
}));

describe('createMeeting', () => {
  test('should call conferenceLoginBuild when not login', () => {
    OAuth.isLogIn = jest.fn().mockImplementationOnce(() => {
      return false;
    });

    // Other tests
  });
});

এটি কোনও ডিফল্ট শ্রেণিকে উপহাস করার জন্য এবং এটি স্থিতিশীল পদ্ধতিগুলি:

jest.mock('../src/to/the/OAuth', () => ({
  OAuth: class {
    public static getOAuthService() {
      return {
        getAuthorizationUrl() {
          return '';
        }
      };
    }
  }
}));

এখানে আপনার শ্রেণীর ধরণ থেকে কিছু জাতীয় রূপান্তর হওয়া উচিত jest.MockedClass। তবে এটি সর্বদা ত্রুটিগুলি দিয়ে শেষ হয়। সুতরাং আমি এটি সরাসরি ব্যবহার করেছি, এবং এটি কাজ করেছে।

test('Some test', () => {
  OAuth.isLogIn = jest.fn().mockImplementationOnce(() => {
    return false;
  });
});

তবে এটি যদি কোনও ফাংশন হয় তবে আপনি এটি উপহাস করতে পারেন এবং কথোপকথনটি করতে পারেন।

jest.mock('../src/to/the/Conference', () => ({
  conferenceSuccessDataBuild: jest.fn(),
  conferenceLoginBuild: jest.fn()
}));
const mockedConferenceLoginBuild = conferenceLoginBuild as 
jest.MockedFunction<
  typeof conferenceLoginBuild
>;
const mockedConferenceSuccessDataBuild = conferenceSuccessDataBuild as 
jest.MockedFunction<
  typeof conferenceSuccessDataBuild
>;

4

আমি এটি খুঁজে পেয়েছি @types/jest:

/**
  * Wrap a function with mock definitions
  *
  * @example
  *
  *  import { myFunction } from "./library";
  *  jest.mock("./library");
  *
  *  const mockMyFunction = myFunction as jest.MockedFunction<typeof myFunction>;
  *  expect(mockMyFunction.mock.calls[0][0]).toBe(42);
*/

দ্রষ্টব্য: আপনি যখন করেন const mockMyFunction = myFunctionএবং এরপরে এমন mockFunction.mockReturnValue('foo')কোনও কিছু ঘটে তখন আপনিও একটি পরিবর্তনশীল myFunction

সূত্র: https://github.com/DefinitelyTypeed/DefinitelyTypeed/blob/master/tyype/jest/index.d.ts#L1089


0

একটি সাম্প্রতিক গ্রন্থাগারটি ব্যাবেল প্লাগইন দিয়ে এই সমস্যাটি সমাধান করে: https://github.com/userlike/joke

উদাহরণ:

import { mock, mockSome } from 'userlike/joke';

const dep = mock(import('./dependency'));

// You can partially mock a module too, completely typesafe!
// thisIsAMock has mock related methods
// thisIsReal does not have mock related methods
const { thisIsAMock, thisIsReal } = mockSome(import('./dependency2'), () => ({ 
  thisIsAMock: jest.fn() 
}));

it('should do what I need', () => {
  dep.mockReturnValueOnce('return');
}

সচেতন থাকুন depএবং mockReturnValueOnceসম্পূর্ণ সুরক্ষিত টাইপ করুন। শীর্ষে, tsserver সচেতন যে depencencyআমদানি করা হয়েছিল এবং depতাই এতক্ষণে tsserver যে সমস্ত স্বয়ংক্রিয় রিফ্যাক্টরিং সমর্থন করে তাও কাজ করবে।

দ্রষ্টব্য: আমি গ্রন্থাগারটি রক্ষণ করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.