আমি কীভাবে জেস্টে একটি মক ডেট সেট করব?


111

আমি আমার প্রতিক্রিয়া উপাদানগুলির জন্য সহায়ক ফাইলে আমার ডেট লজিকের বেশিরভাগটি করতে moment.js ব্যবহার করছি তবে জেস্টে লাতে কীভাবে একটি তারিখ উপহাস করা যায় তা আমি নির্ধারণ করতে সক্ষম হইনি sinon.useFakeTimers()

ঠাট্টা ডক্স শুধুমাত্র মত টাইমার ফাংশন সম্পর্কে কথা বলতে setTimeout, setIntervalইত্যাদি কিন্তু একটি তারিখ নির্ধারণের এবং তারপর চেক যে আমার জন্ম ফাংশন তারা বোঝানো করছি কি সাহায্যের না।

এখানে আমার কিছু জেএস ফাইল রয়েছে:

var moment = require('moment');

var DateHelper = {

  DATE_FORMAT: 'MMMM D',
  API_DATE_FORMAT: 'YYYY-MM-DD',

  formatDate: function(date) {
    return date.format(this.DATE_FORMAT);
  },

  isDateToday: function(date) {
    return this.formatDate(date) === this.formatDate(moment());
  }
};

module.exports = DateHelper;

এবং আমি এখানে জাস্ট ব্যবহার করে সেট আপ করেছি:

jest.dontMock('../../../dashboard/calendar/date-helper')
    .dontMock('moment');

describe('DateHelper', function() {
  var DateHelper = require('../../../dashboard/calendar/date-helper'),
      moment = require('moment'),
      DATE_FORMAT = 'MMMM D';

  describe('formatDate', function() {

    it('should return the date formatted as DATE_FORMAT', function() {
      var unformattedDate = moment('2014-05-12T00:00:00.000Z'),
          formattedDate = DateHelper.formatDate(unformattedDate);

      expect(formattedDate).toEqual('May 12');
    });

  });

  describe('isDateToday', function() {

    it('should return true if the passed in date is today', function() {
      var today = moment();

      expect(DateHelper.isDateToday(today)).toEqual(true);
    });

  });

});

এখন এই পরীক্ষাগুলি পাস হয়েছে কারণ আমি মুহূর্তটি ব্যবহার করছি এবং আমার ফাংশনগুলি মুহুর্তটি ব্যবহার করে তবে এটি কিছুটা অস্থির বলে মনে হয় এবং আমি পরীক্ষাগুলির জন্য একটি নির্দিষ্ট সময় নির্ধারণ করতে চাই।

কীভাবে এটি সম্পাদন করা যায় তার কোনও ধারণা?

উত্তর:


70

মকডেটটি যা new Date()ফেরত দেয় তা পরিবর্তন করতে ঠাট্টা পরীক্ষায় ব্যবহার করা যেতে পারে :

var MockDate = require('mockdate');
// I use a timestamp to make sure the date stays fixed to the ms
MockDate.set(1434319925275);
// test code here
// reset to native Date()
MockDate.reset();

দুর্দান্ত কাজ করেছি কারণ আমি Dateপছন্দ মতো অন্যান্য ফাংশন ব্যবহার করছি valueOf()
রবিন জিম্মারম্যান

143

যেহেতু মুহুর্তগুলি Dateঅভ্যন্তরীণভাবে ব্যবহার করে, তাই আপনি Date.nowসর্বদা একই মুহূর্তটি ফিরতে ফাংশনটি ওভাররাইট করতে পারেন ।

Date.now = jest.fn(() => 1487076708000) //14.02.2017

অথবা

Date.now = jest.fn(() => new Date(Date.UTC(2017, 1, 14)).valueOf())

34
আসল তারিখটি ফিরিয়ে দেওয়া হবে তা নির্ধারণের জন্য এখানে কিছুটা সুন্দর পদ্ধতি রয়েছে:Date.now = jest.fn(() => new Date(Date.UTC(2017, 0, 1)).valueOf());
বিকাশ করছে

4
বা কিছুটা সামান্য Date.now = jest.fn(() => +new Date('2017-01-01');
প্রাক্টিয়েটার

3
বা:Date.now = jest.fn(() => Date.parse('2017-02-14))
জেরেমি ইটন

93

jest.spyOn লকিং সময়ের জন্য কাজ করে:

let dateNowSpy;

beforeAll(() => {
    // Lock Time
    dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000);
});

afterAll(() => {
    // Unlock Time
    dateNowSpy.mockRestore();
});

3
দুর্দান্ত সমাধান; কোনও নির্ভরতা নেই এবং এটিকে পুনরায় সেটযোগ্য করে রাখা একক পরীক্ষায় প্রয়োগ করা সহজ করে তোলে।
কালেব মিলার

14
dateNowSpyভেরিয়েবলের প্রয়োজন নেই এবং এটি জেস্টজেএস.আইও / ডকস / এএন / মক-ফাংশন- পিপি এইচটিএমএল# মকফনমোকরেস্টোরmockReset() অনুসারে অপ্রয়োজনীয় । ইন , আপনি কেবল পারেনafterAllDate.now.mockRestore()
জিমি

এটি দুর্দান্ত তাই আপনার কোনও অতিরিক্ত লাইব্রেরি লাগবে না। আপনি যদি স্থির তারিখ পদ্ধতি ব্যবহার করেন (তবে এটি বেশিরভাগ নয়)
তখনই কাজ করবে

1
@ জিমি Date.now.mockRestore();একটি সম্পত্তি দেয় 'মকরেস্টোর' টাইপ '() => সংখ্যা' ত্রুটিতে নেই
মার্কো ল্যাকোভিক

3
@ মার্কো এটি jest.spyOn হওয়া উচিত (তারিখ, "এখন")। মকরেস্টোর ();
সাব

6

জেস্ট-ডেট-মক আমার দ্বারা রচিত একটি সম্পূর্ণ জাভাস্ক্রিপ্ট মডিউল এবং এটি ঠাট্টার উপরে তারিখটি পরীক্ষা করতে ব্যবহৃত হয়।

import { advanceBy, advanceTo } from 'jest-date-mock';

test('usage', () => {
  advanceTo(new Date(2018, 5, 27, 0, 0, 0)); // reset to date time.

  const now = Date.now();

  advanceBy(3000); // advance time 3 seconds
  expect(+new Date() - now).toBe(3000);

  advanceBy(-1000); // advance time -1 second
  expect(+new Date() - now).toBe(2000);

  clear();
  Date.now(); // will got current timestamp
});

পরীক্ষার ক্ষেত্রে কেবল 3 এপিআই ব্যবহার করুন।

  • অগ্রগতি (এমএস): এমএস দ্বারা অগ্রিম তারিখ টাইমস্ট্যাম্প।
  • অগ্রগতি ([টাইমস্ট্যাম্প]): তারিখকে টাইমস্ট্যাম্পে পুনরায় সেট করুন, ডিফল্টকে 0 এ দিন।
  • ক্লিয়ার (): মক সিস্টেমটি বন্ধ করুন।

তোমার মামলা কি?
অতুল

5

যারা নতুন তারিখের অবজেক্টে পদ্ধতিগুলি উপহাস করতে চান তাদের জন্য আপনি নিম্নলিখিতগুলি করতে পারেন:

beforeEach(() => {
    jest.spyOn(Date.prototype, 'getDay').mockReturnValue(2);
    jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('2000-01-01T00:00:00.000Z');
});

afterEach(() => {
    jest.restoreAll()
});

ধন্যবাদ, এটি কেবল আমারই সমস্যাটি স্থির করেছে।
গ্রেসন ল্যাংফোর্ড

2

পরিবর্তে Date.now()কিছু প্যাকেজ (উদাহরণস্বরূপ moment.js) ব্যবহার new Date()করার কারণে কেবলমাত্র উপহাসের ভিত্তিতে সমস্ত উত্তর সর্বত্র কার্যকর হবে না ।

এই প্রসঙ্গে ভিত্তিক উত্তর MockDateআমি একমাত্র সত্যই সঠিক মনে করি। আপনি যদি কোনও বাহ্যিক প্যাকেজ ব্যবহার করতে না চান তবে আপনি সরাসরি আপনার লিখিতভাবে লিখতে পারেন beforeAll:

  const DATE_TO_USE = new Date('2017-02-02T12:54:59.218Z');
  // eslint-disable-next-line no-underscore-dangle
  const _Date = Date;
  const MockDate = (...args) => {
    switch (args.length) {
      case 0:
        return DATE_TO_USE;
      default:
        return new _Date(...args);
    }
  };
  MockDate.UTC = _Date.UTC;
  MockDate.now = () => DATE_TO_USE.getTime();
  MockDate.parse = _Date.parse;
  MockDate.toString = _Date.toString;
  MockDate.prototype = _Date.prototype;
  global.Date = MockDate;

2

আমি কিছু বিকল্প পদ্ধতির প্রস্তাব করতে চাই।

আপনার যদি স্টাবের দরকার হয় format()(যা স্থানীয় এবং টাইমজোন নির্ভর হতে পারে!)

import moment from "moment";
...
jest.mock("moment");
...
const format = jest.fn(() => 'April 11, 2019')
moment.mockReturnValue({ format })

আপনার যদি কেবল স্টাবের দরকার হয় moment():

import moment from "moment";
...
jest.mock("moment");
...
const now = "moment(\"2019-04-11T09:44:57.299\")";
moment.mockReturnValue(now);

জন্য পরীক্ষার ব্যাপারে isDateTodayউপরে ফাংশন, আমি বিশ্বাস করি সহজ উপায় উপহাস হবে না momentএ সব


2
প্রথম উদাহরণের জন্য, আমি পেয়েছিTypeError: moment.mockReturnValue is not a function
mkelley33

2
কি jest.mock("moment")আপনার আমদানির বিবৃতিগুলির মতো একই পর্যায়ে? অন্যথায়, আপনি এই প্রকল্পে
ডেভিড

1

এইভাবে আমি Date.now()আমার পরীক্ষার জন্য ২০১০ সাল নির্ধারণের জন্য আমার পদ্ধতিটিকে উপহাস করেছি

jest
  .spyOn(global.Date, 'now')
  .mockImplementationOnce(() => new Date(`2010`).valueOf());

1

বিভিন্ন ব্যবহারের ক্ষেত্রে কয়েকটি পঠনযোগ্য উপায় এখানে। আমি মূল বস্তুর রেফারেন্স সংরক্ষণের চেয়ে স্পাই ব্যবহার করা পছন্দ করি, যা দুর্ঘটনাক্রমে অন্য কোনও কোডে ওভাররাইট করা যেতে পারে।

একসময়ের উপহাস

jest
  .spyOn(global.Date, 'now')
  .mockImplementationOnce(() => Date.parse('2020-02-14'));

কয়েকটি পরীক্ষা

let dateSpy;

beforeAll(() => {
  dateSpy = jest
    .spyOn(global.Date, 'now')
    .mockImplementation(() => Date.parse('2020-02-14'));
});

afterAll(() => {
  dateSpy.mockRestore();
});

0

আমি ম্যানুয়াল মোকস ব্যবহার করতে চাই, তাই এটি সমস্ত পরীক্ষায় ব্যবহার করতে পারে।

// <rootDir>/__mocks__/moment.js
const moment = jest.requireActual('moment')

Date.now = jest.fn(() => 1558281600000) // 2019-05-20 00:00:00.000+08:00

module.exports = moment

0

লক্ষ্যটি পরীক্ষার উদ্দেশ্যে উপাদান সরবরাহের সময় যেখানেই ব্যবহৃত হয় সেখানে একটি নির্দিষ্ট তারিখ সহ নতুন তারিখ () উপহাস করা হয়। লাইব্রেরিগুলি ব্যবহার করা একটি ওভারহেড হবে যদি আপনি কেবলমাত্র নতুন তারিখ () এফএনএনকে উপহাস করতে চান।

আইডিয়া হ'ল গ্লোবাল ডেটকে একটি অস্থায়ী পরিবর্তনশীলতে সঞ্চয় করতে, গ্লোবাল ডেটিকে উপহাস করে এবং তারপরে ব্যবহারের পরে টেম্পকে গ্লোবাল ডেটে পুনর্নির্দিষ্ট করে।

export const stubbifyDate = (mockedDate: Date) => {
    /**
     * Set Date to a new Variable
     */
    const MockedRealDate = global.Date;

    /**
     *  Mock Real date with the date passed from the test
     */
    (global.Date as any) = class extends MockedRealDate {
        constructor() {
            super()
            return new MockedRealDate(mockedDate)
        }
    }

    /**
     * Reset global.Date to original Date (MockedRealDate) after every test
     */
    afterEach(() => {
        global.Date = MockedRealDate
    })
}

Usage in your test would be like

import { stubbyifyDate } from './AboveMethodImplementedFile'

describe('<YourComponent />', () => {
    it('renders and matches snapshot', () => {
        const date = new Date('2019-02-18')
        stubbifyDate(date)

        const component = renderer.create(
            <YourComponent data={}/>
        );
        const tree = component.toJSON();
        expect(tree).toMatchSnapshot();
    });
});



আপনার উত্তরটিও ব্যাখ্যা করুন। কোড
রাখাই

1
পরামর্শের জন্য ধন্যবাদ. মন্তব্য সহ আপডেট।
প্রণব এস বালুগারি

0

আমি কেবল এখানে চিম করতে চেয়েছিলাম কারণ আপনি যদি Dateকোনও নির্দিষ্ট স্যুটটিতে বিষয়টিকে উপহাস করতে চান তবে কোনও উত্তরই এই সমস্যার সমাধান করল না।

আপনি প্রতিটি স্যুট, জাস্ট ডকসের জন্য সেটআপ এবং টিয়ারডাউন পদ্ধতি ব্যবহার করে এটি উপহাস করতে পারেন

/**
 * Mocking Date for this test suite
 */
const globalDate = Date;

beforeAll(() => {
  // Mocked Date: 2020-01-08
  Date.now = jest.fn(() => new Date(Date.UTC(2020, 0, 8)).valueOf());
});

afterAll(() => {
  global.Date = globalDate;
});

আশাকরি এটা সাহায্য করবে!


0

আপনি ডেট-ফেকার ব্যবহার করতে পারেন । আপনাকে তুলনামূলকভাবে বর্তমান তারিখটি পরিবর্তন করতে দেয়:

import { dateFaker } from 'date-faker';
// or require if you wish: var { dateFaker } = require('date-faker');

// make current date to be tomorrow
dateFaker.add(1, 'day'); // 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'.

// change using many units
dateFaker.add({ year: 1, month: -2, day: 3 });

// set specific date, type: Date or string
dateFaker.set('2019/01/24');

// reset
dateFaker.reset();

0

জেস্ট 26 পর্যন্ত কোনও তৃতীয় পক্ষের মডিউল ইনস্টল করার প্রয়োজন ছাড়াই "আধুনিক" নকল টাইমার ব্যবহার করে এটি অর্জন করা যেতে পারে: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers

jest
  .useFakeTimers('modern')
  .setSystemTime(new Date('2020-01-01').getTime());
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.