JavaScript-тест (mocha) с файлом 'import' js

Я понимаю module.export и require mannner:

Требование внешнего файла js для тестирования мокки

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

Например, у меня есть код в файле:

app.js

'use strict';
console.log('app.js is running');
var INFINITY = 'INFINITY';

и теперь я хочу протестировать этот код в файле:

test.js

var expect = require('chai').expect;

require('./app.js');


    describe('INFINITY', function()
    {
        it('INFINITY === "INFINITY"',
            function()
            {
                expect(INFINITY)
                    .to.equal('INFINITY');
            });
    });

Тест-код выполняет app.js, поэтому выход:

app.js is running

затем

ReferenceError: INFINITY is not defined

Это не то, что я ожидал.

Я не хочу использовать module.export и писать как

var app = require('./app.js');

и

app.INFINITY и app.anyOtherValue для каждой строки тестового кода.

Должен быть умный способ. Не могли бы вы рассказать мне?

Спасибо.

Ответ 1

ОБНОВЛЕНИЕ: ЗАКЛЮЧИТЕЛЬНЫЙ ОТВЕТ:

Мой предыдущий ответ недействителен, так как eval(code); не используется для переменных.

К счастью, node имеет сильный mehod - vm

http://nodejs.org/api/vm.html

Однако, согласно документу,

Модуль vm имеет много известных проблем и краевых случаев. Если вы столкнулись с проблемами или неожиданным поведением, обратитесь к открытым вопросам на GitHub. Ниже описаны некоторые из самых больших проблем.

поэтому, хотя это работает на поверхности, нужна особая осторожность для такой цели, как тестирование...

var expect = require('chai')
    .expect;

var fs = require('fs');
var vm = require('vm');
var path = './app.js';

var code = fs.readFileSync(path);
vm.runInThisContext(code);

describe('SpaceTime', function()
{
    describe('brabra', function()
    {
        it('MEMORY === "MEMORY"',
            function()
            {
                expect(MEMORY)
                    .to.equal('MEMORY');
            })
    });

});

ПОСЛЕ ВСЕХ; Лучший способ, который я нашел в этом случае, - это написать тестовый код мокки в том же файле.

Ответ 2

Обычно я включаю объект _test, содержащий ссылки на все мои внутренние переменные и функции "private" и выставляю его на экспорт. В вашем случае:

./app.js

var INFINITY = 'infinity';

function foo() {
    return 'bar';
}

exports._test = {
    INFINITY: INFINITY,
    foo: foo
}

./тест/приложение-test.js

var app = require('../app.js')
/* ... */
it('should equal bar', function() {
    expect(app._test.foo()).to.equal('bar');
});
it('should equal infinity', function() {
    expect(app._test.INFINITY).to.equal('infinity');
});