2016-01-06 3 views
0

Я использую Mocha для модульных тестов модулей AMD (requirejs) js. Поскольку модуль должен быть загружен requirejs, тест является асинхронным:Mocha async порядок выполнения

'use strict'; 

var chai = require('chai'); 
var should = chai.should(); 
var requirejs = require('requirejs'); 
requirejs.config({ 
    baseUrl: '../../', 
    paths: { 
     PieWidget: 'tools/scheduler/PieWidget' 
    } 
}); 

describe('PieWidget tests', function() { 
    var PieWidget, pw1, pw2; 
    before('Set up the PieWidget module', function(done) { 
     requirejs(['PieWidget'], function(_) { 
      PieWidget = _; 
      done(); // tell Mocha we are now ready to run the tests 
     }); 
    }); 

    // tests here 
}; 

Для удобства чтения и лаконичности, я хочу сказать:

context('when the constructor is called', function() { 
    pw1 = new PieWidget(); 
    it('should create a valid PieWidget', function() { 
     pw1.should.exist; 
     //todo check validity 
    }); 
}); 

но Мокко запускают эти строки из строя. Чтобы удовлетворить мокко, я должен:

context('when the constructor is called', function() { 
    it('should create a valid PieWidget', function() { 
     pw1 = new PieWidget(); 
     pw1.should.exist; 
     //todo check validity 
    }); 
}); 

, который на мой взгляд является несоответствие между описанием и логикой, или:

context('when the constructor is called', function() { 
    before(function() { 
     pw1 = new PieWidget(); 
    }); 
    it('should create a valid PieWidget', function() { 
     pw1.should.exist; 
     //todo check validity 
    }); 
}); 

который кажется многословным и менее читаемым. Есть ли лучший способ написать этот код?

ответ

0

Два способа, которые вы обнаружили, это то, что касается Мокки.

Mocha работает в два этапа: тестовое обнаружение и выполнение теста. (Я не думаю, что документация говорит об этом). Обратные обратные вызовы, переданные describe и context, называются немедленно от Mocha, во время обнаружения теста. Во время выполнения теста вызываются крючки before, beforeEach. (См. Пример с вызовами console.log, которые выводят номера в этом answer, чтобы увидеть этот порядок в действии.) Во время обнаружения теста вы не можете ничего выполнить, что зависит от кода, выполняемого во время выполнения теста. Это принцип, что ваш код нарушает: new PieWidget() выполняет до ваш before крючок.

Теперь, я бы сказал, что это правильный способ, чтобы написать тест:

context('the constructor', function() { 
    it('should create a valid PieWidget', function() { 
     var pw1 = new PieWidget(); 
     pw1.should.exist; 
     //todo check validity 
    }); 
}); 

Почему? Ваша первоначальная попытка не сработала, потому что Mocha этого не допускает, но предположим, что это так. И предположим, что ваш конструктор сработает. Что Мокка может сделать из этой неудачи? Я могу сказать вам, что сделает Моча. Он просто не выполнил бы никакого теста. Если вам случится тестировать другой объект в вашем пакете, на который не влияет тот факт, что PieWidget неисправен, эти тесты также не будут выполняться. Мокка сразу же сдастся.

Как насчет того, чтобы создать создание в крюке before, который вы обнаружили. Это все еще не очень хорошая идея. Конечный результат будет разным, но причина, по которой это плохая идея, по сути то же самое: Mocha не будет запускать столько тестов, сколько могло бы. Если ваш PieWidget неисправен, тогда произойдет сбой крючка. Mocha интерпретирует сбой в крюке как знак того, что сам набор тестов неисправен и прекратит выполнение. Любой тест, выполненный до сбоя, прекрасен, но любые тесты, которые будут выполняться после сбоя, не будут выполнены.

Выполнение этого способа, показанного выше, гарантирует, что при запуске тестового пакета Mocha будет выполнять максимальное количество тестов. Неисправность new PieWidget() в вашем тесте не будет иметь никакого влияния ни на какой другой тест.

+0

Спасибо за вышеуказанный ответ. Знаете ли вы, что все интерфейсы js test ведут себя так? – bedouger