كيفية حل الوعود في AngularJS، Jasmine 2.0 عندما لا يكون هناك نطاق $ لفرض الملخص؟
-
21-12-2019 - |
سؤال
ويبدو أن الوعود لا يتم حلها في اختبارات Angular/Jasmine إلا إذا قمت بإجبار a $scope.$digest()
.هذا أمر سخيف في المنظمة البحرية الدولية (IMO) ولكنه جيد، لدي هذا العمل عند الاقتضاء (وحدات التحكم).
الموقف الذي أنا فيه الآن هو أن لدي خدمة لا تهتم كثيرًا بأي نطاقات في التطبيق، وكل ما تفعله هو إرجاع بعض البيانات من الخادم ولكن لا يبدو أن الوعد قد تم حله.
app.service('myService', function($q) {
return {
getSomething: function() {
var deferred = $q.defer();
deferred.resolve('test');
return deferred.promise;
}
}
});
describe('Method: getSomething', function() {
// In this case the expect()s are never executed
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
});
done();
});
// This throws an error because done() is never called.
// Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
done();
});
});
});
ما هي الطريقة الصحيحة لاختبار هذه الوظيفة؟
يحرر:الحل للرجوع إليها.من الواضح أنك مجبر على إدخال $rootScope واستيعابه حتى لو كانت الخدمة لا تستخدمه.
it('should get something', function($rootScope, done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
});
$rootScope.$digest();
done();
});
المحلول
تحتاج إلى الحقن $rootScope
في الاختبار الخاص بك والزناد $digest
عليه.
نصائح أخرى
هناك دائما Rootscopeccope، استخدمه
giveacodicetagpre.لذلك كنت أعاني من هذا طوال فترة ما بعد الظهر.بعد قراءة هذا المقال، شعرت أيضًا أن هناك شيئًا خاطئًا في الإجابة، واتضح أن هناك شيئًا ما.لا تقدم أي من الإجابات المذكورة أعلاه شرحًا واضحًا لمكان وسبب الاستخدام $rootScope.$digest
.إذن، هذا ما توصلت إليه.
أولا لماذا؟تحتاج إلى استخدام $rootScope.$digest
عندما تستجيب من حدث غير زاوي أو رد اتصال.قد يتضمن ذلك أحداث DOM خالصة، وأحداث jQuery، ومكتبات Promise التابعة لجهات خارجية أخرى بخلاف $q
وهو جزء من الزاوي.
ثانيا أين؟في التعليمات البرمجية الخاصة بك، وليس الاختبار الخاص بك.ليست هناك حاجة للحقن $rootScope
في الاختبار الخاص بك، فهو مطلوب فقط في الخدمة الزاوية الفعلية الخاصة بك.ويظهر أن هذا هو المكان الذي فشل فيه كل ما سبق في توضيح الإجابة $rootScope.$digest
كما يتم استدعاؤه من الاختبار.
آمل أن يساعد هذا الشخص التالي الذي يأتي لفترة طويلة ولديه نفس المشكلة.
تحديث
لقد حذفت هذه المشاركة بالأمس عندما تم التصويت عليها.اليوم واصلت مواجهة هذه المشكلة أثناء محاولة استخدام الإجابات المقدمة أعلاه.لذا، أحتفظ بإجابتي على حساب نقاط السمعة، وعلى هذا النحو، سأقوم بإلغاء حذفها.
هذا هو ما تحتاجه في معالجات الأحداث غير الزاوية، وأنت تستخدم $q وتحاول الاختبار باستخدام Jasmine.
something.on('ready', function(err) {
$rootScope.$apply(function(){deferred.resolve()});
});
لاحظ أنه قد يلزم تغليفه بمهلة $ في بعض الحالات.
something.on('ready', function(err) {
$timeout(function(){
$rootScope.$apply(function(){deferred.resolve()});
});
});
ملاحظة أخرى.في أمثلة المشكلة الأصلية التي تتصل بها
done
في الوقت الخطأ.تحتاج إلى الاتصالdone
داخلthen
الطريقة (أوcatch
أوfinally
)، من الوعد، بعد أن يحل.أنت تتصل به قبل أن يحل الوعد، وهو ما يسببit
شرط الإنهاء.