2015-02-13 5 views
10

У меня есть метод, который зависит от new Date, чтобы создать объект даты, а затем его обработать. Я тестирую, что манипуляции работают так, как ожидалось, поэтому мне нужно сравнить возвращаемую дату с ожидаемой датой. Для этого мне нужно убедиться, что new Date возвращает то же значение в тесте и в тестируемом методе. Как я могу это сделать?Как издеваться над конструктором как новый Date()

Есть ли способ на самом деле высмеять возвращаемое значение функции-конструктора?

Я мог бы создать модуль, который может потребоваться с помощью функции, предоставляющей объект даты, и может быть высмеян. Но это похоже на ненужную абстракцию в моем коде.

пример функции для тестирования ...

module.exports = { 
    sameTimeTomorrow: function(){ 
    var dt = new Date(); 
     dt.setDate(dt + 1); 
    return dt; 
    } 
}; 

как я издеваться возвращаемое значение new Date()?

+0

Я Здесь немного неуверенно. Не могли бы вы отправить код? Я предполагаю, что вы должны передать 'definedDate' для обеих функций, и когда вы назначаете дату, которую вы должны выполнить var varDate = definedDate || new Date(); ', чтобы проверить, передано ли вам значение тестирования или нет. Затем вы можете включить/отключить, передав/не передав его. – somethinghere

+0

обновлен с помощью (надуманного) примера. Я действительно могу добавить необязательный аргумент даты и передать это для моего тестирования. Однако это не так хорошо, как api, а также мой реальный прецедент уже имеет 3 аргумента. Поэтому я не хочу добавлять другого, тем более, что это может сильно испортить намерение метода. –

ответ

0

Вот что я делаю сейчас, и это работает и не загромождает подпись моего метода.

newDate.js

module.exports = function(){ 
    return new Date(); 
}; 

someModule.js

var newDate = require('newDate.js'); 
module.exports = { 
    sameTimeTomorrow: function(){ 
    var dt = newDate(); 
     dt.setDate(dt.getDate() + 1); 
    return dt; 
    } 
}; 

someModule-test.js

jest.dontMock('someModule.js'); 

describe('someModule', function(){ 

    it('sameTimeTomorrow', function(){ 
    var newDate = require('../../_app/util/newDate.js'); 
     newDate.mockReturnValue(new Date(2015, 02, 13, 09, 15, 40, 123)); 

    var someModule = require('someModule.js'); 

    expect(someModule.sameTimeTomorrow().toString()).toBe(new Date(2015, 02, 14, 09, 15, 40, 123).toString()); 
    }); 

}); 
+2

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

1

Вы можете использовать Жасмин spyOn (Шутка строится на жасмин) издеваться Прототип даты для getDate следующим образом:

spyOn(Date.prototype, 'setDate').and.returnValue(DATE_TO_TEST_WITH); 

SpyOn также будет очищаться после его самообслуживания и будет продолжаться только в рамках теста.

0

Вы можете заменить конструктор Date тем, что всегда возвращает жестко запрограммированную дату, а затем верните его в нормальное состояние, когда это будет сделано.

var _Date = null; 

function replaceDate() { 
    if (_Date) { 
    return 
    }; 

    _Date = Date; 

    Object.getOwnPropertyNames(Date).forEach(function(name) { 
    _Date[name] = Date[name] 
    }); 

    // set Date ctor to always return same date 
    Date = function() { return new _Date('2000-01-01T00:00:00.000Z') } 

    Object.getOwnPropertyNames(_Date).forEach(function(name) { 
    Date[name] = _Date[name] 
    }); 
} 

function repairDate() { 
    if (_Date === null) { 
    return; 
    } 

    Date = _Date; 
    Object.getOwnPropertyNames(_Date).forEach(function(name) { 
    Date[name] = _Date[name] 
    }); 

    _Date = null; 
} 

// test that two dates created at different times return the same timestamp 
var t0 = new Date(); 

// create another one 100ms later 
setTimeout(function() { 
    var t1 = new Date(); 

    console.log(t0.getTime(), t1.getTime(), t0.getTime() === t1.getTime()); 

    // put things back to normal when done 
    repairDate(); 
}, 100); 
1

Вы можете переопределить Дата конструктор с издевались функцией, которая возвращает свой сконструированный объект Date со значением даты, указанной:

var yourModule = require('./yourModule') 

test('Mock Date',() => { 
    const mockedDate = new Date(2017, 11, 10) 
    const originalDate = Date 

    global.Date = jest.fn(() => mockedDate) 
    global.Date.setDate = originalDate.setDate 

    expect(yourModule.sameTimeTomorrow().getDate()).toEqual(11) 
}) 

Вы можете проверить пример здесь: https://repl.it/@miluoshi5/jest-mock-date