2015-10-06 4 views
0

Я пытаюсь перейти к Firebase для своих данных в своих тестах и ​​вместо этого возвращать некоторые простые результаты. Я не хочу проверять, работает ли код Firebase, но мои фабрики работают с возвратом данных.AngularJS Тестирование с помощью Mocha и Sinon - Mocking Firebase Зависимости

У меня есть следующие заводы:

// Get Firebase Reference 
angular.module('MyApp').factory('FireBaseData', function(FIREBASE) { 
    var FireBaseReference = new Firebase(FIREBASE.URL); // FIREBASE.URL = xxx.firebaseio.com 
    return FireBaseReference; 
}) 

// Get the Firebase Array of Team Records 
angular.module('MyApp').factory('AllTeams', ["FireBaseData", "$firebaseArray", 
    function(FireBaseData, $firebaseArray) { 
     return $firebaseArray(FireBaseData.child('Teams')); 
    } 
]); 

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

'use strict'; 

var $MockFirebaseArray = function(ArrayWithData) { 
    return ArrayWithData; 
}; 

var $MockFirebaseObject = function(ObjectWithData) { 
    return ObjectWithData; 
}; 

var MockFirebaseData = function() { 
    return { 
     child: function(StringValue) { 
      return ""; 
     } 
    }; 
}; 

тесты с издевается:

'use strict'; 

describe('Firebase Mocks', function() { 
    var TestArray = [ 
     { 'aString': 'alpha', 'aNumber': 1, 'aBoolean': false }, 
     { 'aString': 'bravo', 'aNumber': 2, 'aBoolean': true }, 
     { 'aString': 'charlie', 'aNumber': 3, 'aBoolean': true }, 
     { 'aString': 'delta', 'aNumber': 4, 'aBoolean': true }, 
     { 'aString': 'echo', 'aNumber': 5 } 
    ]; 

    describe('MockFirebaseData', function() { 
     var TestFirebase = MockFirebaseData(); 
     it('should return empty text ("") from FireBaseData', function() { 
      assert.equal('', TestFirebase.child('SomeNode')); 
     }); 
    }); 

    describe('$MockFirebaseArray', function() { 
     it('should have the data array passed', function() { 
      var TestData = $MockFirebaseArray(TestArray); 
      assert.equal(TestArray.length, TestData.length); 
     }); 
    }); 

    describe('$MockFirebaseObject', function() { 
     it('should have the data object passed', function() { 
      var TestData = $MockFirebaseObject(TestArray[0]); 
      assert.equal(TestArray[0].length, TestData.length); 
      assert.deepEqual(TestArray[0], TestData); 
     }); 
    }); 
}); 

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

Тест Фабрика: вернулся

describe('Teams Module', function() { 
    beforeEach(module('MyApp'));  // Load My Application 

    describe('AllTeams Array', function() { 
     // Create Test Data 
     var TeamData = [ 
      { "Key": 1, "Name":"Team 1", "Logo": "Team1.jpg" }, 
      { "Key": 3, "Name":"Team 3", "Logo": "Team3.jpg" }, 
      { "Key": 2, "Name":"Team 2", "Logo": "Team2.jpg" }, 
     ]; 

     beforeEach(function() { 
      module(function($provide) { 
       var MockData = MockFirebaseData(); 
       $provide.value('FireBaseData', MockData); 
       $provide.value('$firebaseArray', $MockFirebaseArray(TeamData)); 
      }); 
     }); 

     it('can get an instance of AllTeams factory', inject(function(AllTeams) { 
      assert.isDefined(AllTeams); 
     })); 
    }); 
}); 

Ошибка:

PhantomJS 1.9.8 (Windows 7 0.0.0) 
Teams Module 
AllTeams Array 
can get an instance of AllTeams factory FAILED 
TypeError: '[object Object],[object Object],[object Object]' is not a function (evaluating '$firebaseArray(FireBaseData.child('Teams'))') 
    at app/Team.js:9 
+0

'$ MockFirebaseArray' возвращает массив. Но тогда в 'AllTeams' вы пытаетесь использовать его как функцию. –

+0

@AnidMonsur Я пытаюсь исправить свою фабрику, чтобы проверить, что она возвращает, так как я считаю, что вызов $ firebaseArray() обычно возвращает данные массива. Я пытаюсь получить то же самое для своей фабрики. Может быть, моя инъекция неисправна? Я хочу подтвердить, что возвращаю то, что ожидаю, поэтому я могу использовать этот же структурированный макет для работы с контроллером, который использует AllTeams для отображения списков. –

+0

Возможно, вам будет лучше использовать [mockfirebase] (https://github.com/katowulf/mockfirebase), чтобы имитировать ссылки Firebase и оставить методы AngularFire такими, какие они есть. –

ответ

1

Вместо:

$provide.value('$firebaseArray', $MockFirebaseArray(TeamData)); 

попробовать это:

$provide.value('$firebaseArray', $MockFirebaseArray); 

Я считаю, что это то, что вы намеревались сделать в первую очередь. Когда вы введете, ваш завод сможет вызвать $firebaseArray в качестве функции.

+0

Это похоже на мою текущую ошибку. Еще один быстрый вопрос заключался в том, как передать массив данных, чтобы вернуть его? В моей исходной строке отправка массива возвращает его. Теперь я хочу проверить, что мои AllTeams возвращают 3 записи, чтобы я мог их обработать. –

+1

Он по-прежнему возвращает то, что вы проходите. Но вы передаете пустую строку, потому что это то, что возвращает 'MockData.child()'. –

+0

Большое спасибо. Это то, что я искал. Мои тесты теперь проходят с хорошим покрытием кода моих заводов. Теперь мне просто нужно выяснить, как на самом деле переместить библиотеку mockfirebase, чтобы я мог протестировать остальные функции добавления/удаления Firebase. –

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