2015-04-03 2 views
14

Я относительный новичок на все вещи JavaScript, Node.js, мокко и т.д.Как переменная область видится в рамках теста Mocha?

В моем коде у меня есть объект Unit, который имеет disable(), который устанавливает отключенное свойство верно и isDisabled(), который возвращает отключенное свойство , Он также имеет метод nextTurnReset(), который сбрасывает устройство в начале следующего поворота. Я написал тестовый набор, чтобы проверить это поведение. Сначала я отключу объект, а затем попытаюсь проверить, отключен ли он. Однако единичная переменная внутри моего первого теста, которая находится в анонимной функции, переданной методу it() Mocha, находится в состоянии без отключения, как я наблюдал с отладчиком узла.

describe('#disable()', function() { 
    var unit = tests.newUnit(); 
    unit.disable(); 
    debugger; 
    it('disabled off turn?', function() { 
     debugger; 
     (unit.isDisabled()).should.be.exactly(true); 
    }); 
    unit.nextTurnReset(); 
    it('disabled on next turn?', function() { 
     (unit.isDisabled()).should.be.exactly(true); 
    }); 
    unit.nextTurnReset(); 
    it('disabled on 2nd turn?', function() { 
     (unit.isDisabled()).should.be.exactly(false); 
    }); 
}); 

для записи первые два теста не срабатывают, и последний успешно показывает, что устройство никогда не отключается вообще.

с помощью Repl Узла отладчика: После первого debugger; заявления unit.disabled == true, но после второго debugger; заявления unit.disabled == false. Я ожидаю, что значение будет истинным в обоих случаях.

Любая идея, почему это так? Кроме того, каков правильный способ написания тестов Mocha для получения ожидаемого результата?

Большое спасибо!

ответ

12

Переменная область видимости в Mocha точно такая же, как и в любом другом коде JavaScript. Ваша проблема в том, что вы не понимаете, в каком порядке Mocha выполнит ваш код. Это то, что происходит:

  1. создается экземпляр блока и вызовите disable на него.

  2. Вы регистрируете свой первый тест. Вот что делает it: он регистрирует тест для будущего исполнение. Тест не выполняется сейчас.

  3. Вы вызываете unit.nextTurnReset();, который сбрасывает состояние вашего объекта.

  4. Вы регистрируете свой второй тест. Опять он не исполняется сейчас.

  5. Сбрасывает объект снова.

  6. Вы регистрируете свой последний тест.

После этого Mocha проводит тесты, которые вы зарегистрировали, и запускает их. К моменту запуска ваших тестов ваш объект находится в состоянии сброса, а не отключен.

Мне кажется, что, учитывая желаемое поведение вы описываете, ваш код должен быть:

describe('#disable()', function() { 
    var unit = tests.newUnit(); 

    beforeEach(function() { 
     unit.nextTurnReset(); 
    }); 

    it('disabled off turn?', function() { 
     unit.disable(); 
     (unit.isDisabled()).should.be.exactly(true); 
    }); 

    it('disabled on next turn?', function() { 
     (unit.isDisabled()).should.be.exactly(false); 
    }); 
}); 

Код передается beforeEach выполняется перед каждым испытанием вы зарегистрированный таким образом он сбрасывает объект на правильное время.

0

Передача состояния между примерами не очень хорошая практика. Что произойдет, если вам нужно запустить тесты в случайном порядке? Или кто-то в проекте решает переместить примеры?

Для меня, имеющего следующих два примера, кажется, достаточно, чтобы проверить блок # отключить правильно

describe('#disable()', function() { 
    it('gets disabled when called on an enabled', function() { 
     var unit = tests.newUnit(); 
     unit.disable(); 

     (unit.isDisabled()).should.be.exactly(true); 
    }); 

    it('gets enabled when called on a disabled', function() { 
     var unit = tests.newUnit(); 
     unit.disable(); 
     unit.disable(); 

     (unit.isDisabled()).should.be.exactly(false); 
    }); 
}); 
+1

ОП делаю это неправильно, но сброс арматуры в известном состояние между испытаниями является полностью обоснованной стратегией. Если создание всего прибора не является обременительным, я предпочитаю его создавать заново в каждом тесте, но иногда лучше переустановить его в известное состояние между тестом, а не создавать дорогостоящие светильники заново. Вызов 'unit.nextTurnReset()' в методе 'beforeEach' сбрасывает тестовое устройство в известное состояние * между * тестами. Так как он находится в 'beforeEach', вызов' unit.nextTurnReset() 'перед каждым тестом не зависит от того, какие тесты запускаются или не запускаются, или порядок проверки. – Louis

Смежные вопросы