جافاسكريبت - كيف أحل وعدًا في اختبار وحدة AngularJS
أنا أستخدم إعداد كاما/جاسمين الأساسي لاختبار رمز Angular الخاص بي. إليك اختباري:
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
describe('main controller', function() {
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
beforeEach(inject(function($controller, $rootScope, $q) {
scope = $rootScope.$new();
$controllerConstructor = $controller;
q = $q;
mockSuperheroData = {
getSuperheroes: function() {
deferred = q.defer();
return deferred.promise;
}
};
ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
}));
it('should set the result of getResource to scope.heroes', function() {
scope.getHeroes();
expect(scope.heroes).toBe(100);
});
}
scope.getHeroes() يستدعي mockSuperheroData.getSuperheroes() الذي يرجع وعدًا (Promise). كيف يمكنني إجبار الوعد على إرجاع ما أريده في اختبار الوحدة؟ أين يمكنني التوصيل بالوعد لتزييف نتيجته؟
الإجابة رقم 1
كيف أجبر الوعد على إرجاع ما أريده في اختبار الوحدة؟
بشكل أساسي، ستحتاج إلى استدعاء resolve على الـ Deferred:
deferred.resolve(100);
يمكنك وضع ذلك مباشرة قبل return deferred.promise أو في setTimeout غير متزامن.
الإجابة رقم 2
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
describe('main controller', function() {
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q, rootScope;
beforeEach(inject(function($controller, $rootScope, $q) {
scope = $rootScope.$new();
$controllerConstructor = $controller;
q = $q;
rootScope = $rootScope;
mockSuperheroData = {
getSuperheroes: function() {
deferred = q.defer();
return deferred.promise;
}
};
ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
}));
it('should set the result of getResource to scope.heroes', function() {
scope.getHeroes();
deferred.resolve(100);
rootScope.$apply();
expect(scope.heroes).toBe(100);
});
});
يجدر بالذكر أنه نظرًا لأن $q مدمج مع $rootScope، فلا تحتاج فقط إلى حل الكائن المؤجل، بل تحتاج أيضًا إلى نشر التغييرات عن طريق استدعاء $rootScope.$apply.
كتبت مدونة عن السخرية من وعود Angular في projectpoppycock
وقد كتبت مثالاً عملياً، مع اختبارات، على plunkr
أنا حقًا أحب الطريقة التي تقوم فيها بحقن الخدمة الوهمية كاعتماد للمتحكم باستخدام خدمة $controller، قد أحتاج إلى إعادة النظر في طريقتي في القيام بذلك. طريقتك أفضل :) شكرًا!
