несколько странный код javascript работает во всех основных браузерах, но не работает с phantomjs/qunit

Я работаю над приложением с интерфейсом javascript/html и серверной службой REST. В основном я работаю над серверной службой, но пытаюсь добавить модульные тесты javascript в сборку. У меня был кто-то, кто помог мне с настройкой среды тестирования javascript, используя phantomjs, qunit и jstestrunner, на все из которых ссылается Maven.

Я написал тривиальный модульный тест для модуля (назовем его «data.daily.js»), который начинается так:

Data.Daily = new Function();
Data.Daily.prototype = {

Просто для ясности: этот код запускается каждый день в рабочей среде и, по-видимому, отлично работает во всех основных браузерах (FF, IE и Chrome).

Тест выглядит так:

requirejs.config({ shim: { 'data.daily': ['config'] } });
require(['data.daily'], function() {
    'use strict';
    module('data.daily');
    test('data.daily.test.initialize', function() {
        var dataDaily   = new Data.Daily();
        dataDaily.initialize(Config.AJAX_DAILY_DATA_BASE_URL, Config.MOCKDATA_AJAX_DAILY_DATA_BASE_URL);
        deepEqual(dataDaily.getData(), {}, "object is \"" + JSON.stringify(dataDaily.getData()) + "\", but it should be empty object");
    });
});

Когда я запускаю этот тест, он терпит неудачу следующим образом:

  ReferenceError: Can't find variable: Data, source: http://localhost:9080/data.daily.js:5
  [data.daily] data.daily.test.initialize: failed: 1 passed: 0
  Died on test #1     at http://localhost:9080/js/qunit.js:425
at http://localhost:9080/js/data.daily.test.js:17
at http://localhost:9080/js/require.js:1682
at http://localhost:9080/js/require.js:983
at http://localhost:9080/js/require.js:1194
at http://localhost:9080/js/require.js:129
at http://localhost:9080/js/require.js:1237
at each (http://localhost:9080/js/require.js:58)
at http://localhost:9080/js/require.js:1238
at http://localhost:9080/js/require.js:1043
at http://localhost:9080/js/require.js:1224
at http://localhost:9080/js/require.js:882
at callGetModule (http://localhost:9080/js/require.js:1249)
at http://localhost:9080/js/require.js:1578
at http://localhost:9080/js/require.js:1703: Can't find variable: Data, source: ReferenceError: Can't find variable: Data

Единственный способ заставить этот тест работать - изменить "data.daily.js" таким образом, добавив строку перед существующими строками:

var Data    = {};
Data.Daily = new Function();
Data.Daily.prototype = {

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

Обратите внимание, что вместо этого я попытался изменить тестовый сценарий, добавив строку «var Data = {}» перед строкой «var dataDaily = new Data.Daily()», но это не дало никакого эффекта.

Итак, кто-нибудь может объяснить, что здесь происходит? Почему исходный код работает, если он не прошел тест. Есть ли что-то странное в том, как работает «require.js», что заставляет это происходить? Почему тест не сработал, добавив строку в тест вместо CUT (тестируемого кода)?


person David M. Karr    schedule 14.08.2013    source источник
comment
Единственный способ, который может работать в любом контексте браузера, — это если код идет после некоторого другого кода, который создает глобальную переменную с именем Data. Если вы не объявите переменную, а затем попытаетесь разыменовать ее с помощью оператора ., вы всегда получите ошибку.   -  person Pointy    schedule 14.08.2013
comment
Загружаются ли в вашем производственном коде какие-либо другие сценарии, которые не загружаются в ваших тестах? Как указал @Pointy, что-то должно создавать этот глобальный Data, иначе он потерпит неудачу.   -  person Mike Cluck    schedule 14.08.2013
comment
Вздох. Я собирался сказать, что уже перерыл всю кодовую базу в поисках ссылок на Data и не нашел. Однако я только что понял, что искал для этого только файлы *.js. Наконец-то я нашел его в index.html. Я теперь, по крайней мере, понимаю эту часть. Однако до сих пор неясно, почему я не могу заставить тест работать, просто добавив строку var Data = {} в сам тестовый скрипт.   -  person David M. Karr    schedule 14.08.2013


Ответы (1)


Хорошо, мне удалось решить это.

Назначение действительно присутствует в существующем производственном коде, я просто не додумался поискать его в файлах ".html" раньше. Когда я не нашел его в файлах ".js", я подумал, что происходит что-то еще.

Причина, по которой не получилось поместить строку в тестовый сценарий, заключалась в том, что я помещал строку не в то место. На самом деле ошибка возникает во время настройки, а не при выполнении самого теста, поэтому назначение должно было быть до вызова «requirejs.config()». Теперь тест работает без необходимости модификации CUT.

person David M. Karr    schedule 14.08.2013