Mocha: يفشل this.timeout () عند استخدام وظائف سهم ES6

تم إنشاؤها على ٢١ ديسمبر ٢٠١٥  ·  59تعليقات  ·  مصدر: mochajs/mocha

عند استخدام Node> = 4 مع "use strict" وبناء جملة ES6 لوظائف الأسهم ، يفشل mocha:

describe('foo', () => {
  this.timeout(100);
});

# => TypeError: this.timeout is not a function

يعمل استخدام بناء جملة ES5:

describe('foo', function() {
  this.timeout(100);
});

إذن ، أي نوع من الحيل القبيحة التي يستخدمها المخاوي مع this ؟

faq

التعليق الأكثر فائدة

شكرا.

لماذا الكثير من "السحر" الذي ينتج عنه في النهاية مشاكل؟ لما لا هذا ؟:

var mocha = require('mocha');

mocha.describe('foo', (suite) => {
  suite.timeout(100);

  suite.it('must love bar', () => ... );  
});

لا توجد كرات أرضية ، ولا سحر إشكالي ... ولكن فقط جافا سكريبت.

ال 59 كومينتر

إنه يربط الوظيفة بسياق الاختبار ، والذي لا يمكن إجراؤه عند استخدام وظائف الأسهم. من http://mochajs.org/

screen shot 2015-12-21 at 8 06 34 am

اسف بشأن ذلك!

شكرا.

لماذا الكثير من "السحر" الذي ينتج عنه في النهاية مشاكل؟ لما لا هذا ؟:

var mocha = require('mocha');

mocha.describe('foo', (suite) => {
  suite.timeout(100);

  suite.it('must love bar', () => ... );  
});

لا توجد كرات أرضية ، ولا سحر إشكالي ... ولكن فقط جافا سكريبت.

ما تقترحه هو تغيير جذري كبير وشيء تتم مناقشته في https://github.com/mochajs/mocha/issues/1969#issuecomment-160925915 قد تقدم إعادة الكتابة تلك الأنواع من الدلالات :)

من الجيد معرفة ذلك. شكرا.

ibc حسنًا ، يجب أن يكون

var mocha = require('mocha');

mocha.describe('foo', (suite) => {
  suite.timeout(100);

  suite.it('must love bar', (suite) => ... );  
});

ولكن هل الوسيطتان المختلفتان في المجموعة من نفس النوع؟ ربما لا ، إذن لديك أسماء متغيرات مختلفة لتعكس الأنواع المختلفة مثل ذلك

var mocha = require('mocha');

mocha.describe('foo', (suite) => {
  suite.timeout(100);

  suite.it('must love bar', (test) => ... );  
});

على أي حال ، لا يمكن استخدام عامل تشغيل الأسهم في الوظائف التي تتوقع سياقات.

لا أتخيل كسر واجهة مستخدم BDD لـ # 1969 - فورًا من الخفاش ، على أي حال - على الرغم من أنني يمكن إقناعي. كنت آمل أن نحافظ على واجهة برمجة التطبيقات الحالية ، وأن نقدم حزمة منفصلة تحتوي على واجهة مستخدم BDD. ستشحن Mocha بإصدار من BDD UI الذي يستخدم واجهة برمجة التطبيقات الحالية ، ولكن بعد ذلك يمكننا إصدار إصدار جديد من حزمة BDD UI باستخدام lambdas بعد ذلك - يمكن للمستخدمين اختيار ما إذا كانوا يريدون الترقية صراحة إلى تلك الحزمة أم لا.

ربما يحل بناء جملة ES6 البديل لـ describe أو غلاف suite هذه المشكلة:

describe({ feature: 'create stuff' , do () {
    it('abc', () => {
    }); 
}})

هذا من شأنه أن يسمح على الأقل بالربط على مستوى المجموعة.

أي تحديث على هذا؟ لدي هذا

mocha = require('mocha');

mocha.describe('test', (suite) => {

suite.timeout(500);

suite.it('test', (done)=>
          )
    }
)

والحصول على TypeError: لا يمكن قراءة الخاصية timeout لـ undefined

mroien هذا ليس خطأ موكا. صيغة السهم ليست بديلاً 1: 1 لـ function . يرجى قراءة حدوده

هل جاء أي شيء من هذا؟ يعجبني الحل المقترح ، فقط من أجل حبي لوظائف الأسهم والنفور من "هذا" عندما لا يكون مطلوبًا

نظرًا لأن timeout لا يتعلق إلا بـ done ، فلماذا لا تقوم ببساطة بإرفاق وظيفة المهلة بالوظيفة المنجزة.

it('makes sense', done => {
    done.timeout(100);
});

nomilous هذا ما زال لا يعمل. لدي مشكلة مماثلة. ما يصلح لحالتي هو استدعاء setTimeout داخل كتلة it . على سبيل المثال

it('description', done => {
     const func = () => {
          // assertions
     };
     setTimeout(func, 10000);
});

nomilous المتزامن أو الحالات التي تعيد الوعد يمكن أن يكون لها مهلة أيضًا.

@ andela-engmkwalusimbi هذا ليس من المفترض أن يعمل. كما كتب boneskull :

mroien هذا ليس خطأ موكا. صيغة السهم ليست بديلاً 1: 1 للوظيفة. يرجى قراءة حدوده

بالنسبة إلى كل شخص لا يزال يتساءل عن هذا الأمر ، تأكد من فهمك لما تشير إليه وظيفة السهم ، ثم عد إلى هنا واقرأ (هناك الكثير من الموارد التي يمكن أن تشرح ذلك بشكل أفضل بكثير مما أستطيع).

الطريقة الوحيدة التي ستعمل بها وظائف هذا السهم في هذه الحالة هي إذا قمنا بتغيير واجهة برمجة تطبيقات bdd لتمرير كائن context إلى كل رد اتصال في Runnable (خطافات ، اختبارات) ، بدلاً من الاستفادة من this . هذه ليست فكرة سيئة ، لكنها زلزال لتغيير جذري ، لذلك لن يحدث أبدًا. بدلا من هذا:

it('should do something', function (done) {
  this.timeout(9000);
  // stuff
  done();
});

سيبدو مثل هذا:

it('should do something', (context, done) => {
  context.timeout(9000);
  done();
});

سيؤدي ذلك إلى كسر كل اختبار Async Mocha في الوجود ، بغض النظر عما إذا كان متوافقًا مع الإصدارات السابقة:

it('should do something', function (context, done) {
  // context is unused, but 'done' is now the second parameter
  this.timeout(9000);
  done();
});

يمكننا توفير تطبيق بديل bdd يقوم بذلك ، ومع ذلك - لن يكون الخيار الافتراضي.

هذا عن الشرح الأكثر شمولاً لدي عن "مكان هذه المشكلة". :ابتسامة:

ربما يمكن أن تؤخذ في الاعتبار للإصدار الرئيسي المقبل؟ لا أعتقد أنه تغيير مهم بما فيه الكفاية لإنشاء تطبيق bdd بديل. قد يساعد وجود الحجج المسماة في التطوير المستقبلي أيضًا وربما إنشاء طريقة بسيطة لإضافة نوع من البرامج الوسيطة للاختبار مثل:

it('should do something', function ({ context, done }) { ...

يمكننا توفير تطبيق bdd بديل يقوم بذلك ، ومع ذلك - لن يكون الأمر الافتراضي.

boneskull ستكون واجهة bdd-es6 الجديدة رائعة :)

على الرغم من أنني مغرم بوظائف الأسهم المفيدة حقًا على سبيل المثال ، وظائف المصفوفة مثل .filter(i => i.val) ، ما هي مشكلة استخدام الوظائف العادية؟ أعتقد أنه من المفيد جدًا أن أشرح ذلك على مستوى العالم ، لذا لا يتعين علي طلبها في كل مرة. أيضًا منذ متى يكون السحر this ، فقط لأنك لا تفهم وظائف (السهم)؟ بالتأكيد لا أرغب في تقديم متغير في كل مرة يمكنني فيها إعادة الوعود ، وإلا كنت سأنتقل إلى شيء مثل ava منذ وقت طويل. فيما يتعلق بساطة المخاوي ، أعتقد أنه لا ينبغي أن يكون هناك أي تغيير كبير في الوظائف العادية / السهم الموصوفة في # 1969. ويرجى عدم إخباري بأن وظائف الأسهم أسرع في الكتابة لأن المحرر الخاص بك يمكنه تحويل f إلى function () {\n\t\n} .

لست واضحًا ، هل هناك حل لانتهاء مهلة مكالمة before() التي تستخدم وظائف الأسهم؟

    before( async function () {
      data = await provider.getData();
      console.log(data);
      this.timeout(30*1000);
    });

ليس له تأثير. لا يزال يحصل على مهلة 4 ثوان هنا. هذا هو الشيء الوحيد البطيء في مجموعة الاختبار الخاصة بي. يمكنني وضع مهلة على 30 ثانية في mocha.opts لحل المشكلة ، لكنني لا أحتاج حقًا إلى جميع الاختبارات حتى تنتهي المهلة بعد 30 ثانية فقط مكالمة api واحدة عندما تكون 4s جيدة لـ 99٪ منها.

إليك كيفية حلها في هذه الأثناء (لاحظ أن أول describe() يستخدم function بدلاً من بنية السهم السمين:

describe('Search API', function () {
    this.timeout(30*1000);

    context('search', () => {
        let data;

        before( async () => {
          data = await provider.getSearch();
        });

        it('returns results', () => {
          expect(data).to.exist;
          expect(data.results).to.be.instanceOf(Array);
          expect(data.results.length).to.be.above(0);
        });
    })
});

chovy أنت تقوم بتعيين المهلة بعد حدوث المهلة في await provider.getData() .
جرب استخدام هذا بدلاً من ذلك:

before(async function () {
  this.timeout(30*1000); // set timeout first, then run the function
  data = await provider.getData();
  console.log(data);
});

أنا غير واضح ، هل هناك حل لانتهاء مهلة المكالمة السابقة () التي تستخدم وظائف السهم؟

فقط لتوضيح هذا الأمر: لا توجد حاليًا طريقة لاستدعاء Mocha timeout باستخدام وظائف الأسهم. أي مناقشة للبدائل (مهما كانت جديرة بالتقدير) هي مناقشة حول واجهات جديدة محتملة (أو معدلة على الأقل).

هناك شيء كان يدور في ذهني لفترة من الوقت وهو القدرة على القيام به:

it('...', (done) => {
  ...
  done()
})

و

it('...', (t) => {
  t.timeout(500)
  t.tag('integration', 'api')
  ...
  t.done()
})

باستخدام نفس الواجهة الافتراضية.

يتيح لك دعم كلاهما في نفس الواجهة الافتراضية البدء في استخدام وظائف الأسهم في قاعدة بيانات موجودة. تجدر الإشارة إلى أن بناء الجملة (done) الموجود في العديد من البرامج التعليمية عبر الإنترنت سيظل يعمل ، بدون إشارات أو أي شيء.

لذلك في هذا التطبيق ، تحصل على وظيفة done التقليدية كمعامل ، ولكن مع إضافة وظائف الأداة المساعدة كخصائص لكائن الوظيفة done .

يؤدي استخدام this.timeout() إلى اختفاء الوقت المنقضي في التقرير.

dasilvacontin ليس لدي فكرة لماذا لم نفكر في ذلك سابقًا. هذه فكرة ممتازة.

dasilvacontin أوه ، أتذكر. لأنه عليك أن تسميها. قد لا ترغب في ذلك.

عُذْرًا ، هَلْ يُمْكِنُ أَنْ تَفصّلَ عن "have to call it" ،boneskull؟ هل تتحدث عن المشكلات التي يعتقد موكا أن الاختبار غير متزامن؟

في 29 كانون الثاني (يناير) 2017 ، الساعة 05:54 ، كتب كريستوفر هيلر [email protected] :

dasilvacontin أوه ، أتذكر. لأنه عليك أن تسميها. قد لا ترغب في ذلك.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بكتم صوت الموضوع.

أيضًا ، كيف تعلن عن نيتك في إجراء اختبار غير متزامن عند استخدام "t"؟

في الشريط ، عليك دائمًا استدعاء 't.done' ('t.end' في واجهة برمجة التطبيقات الخاصة بهم) ، أو تعيين المقدار المتوقع من التأكيدات ('t.plan').

هل من الممكن إضافة وسيطة ثالثة إليها () مع الخيارات؟ لن يكسر ذلك API.

it ('accepts lambda', (done)=>{ doWork();  done(); }, {timeout:60000});

تضمين التغريدة

ماذا لو كان بدلاً من وضع السياق أولاً ، كان ثانيًا اختياريًا؟

بدلا من هذا:

it('should do something', function (done) {
  this.timeout(9000);
  // stuff
  done();
});

سيبدو مثل هذا:

it('should do something', (done, context) => {
  context.timeout(9000);
  done();
});
it('should do something', function (done, context) {
  // context is unused, but 'done' is now the second parameter
  this.timeout(9000);
  done();
});

يمكننا توفير تطبيق bdd بديل يقوم بذلك ، ومع ذلك - لن يكون الأمر الافتراضي.

هذا عن الشرح الأكثر شمولاً لدي عن "مكان هذه المشكلة". 😄

أو إذا كان يجب أن يكون السياق محددًا محددًا

it('should do something', function (done, override) {
  // context is unused, but 'done' is now the second parameter
  override.timeout(9000);
  done();
});

لكنني سأستخدم واجهة غير افتراضية أيضًا :)

الجانب السلبي لأي حل يتطلب done هو أنه يجب عليك استخدام done حتى لو كان إرجاع الوعد أسهل. أتحدث عن نفسي ، أعلم أنني أفضل كتابة function و return .then(()=>{done()}, done) !

Flamenco هذه فكرة مثيرة للاهتمام ، على الرغم من أنني قد أفضل أن تكون الوظيفة أخيرًا (نعم ، إنها أكثر "سحرية" من الناحية الفنية بهذه الطريقة ، ولكن ، دعنا نواجه الأمر ، من السهل التحقق مما إذا كانت المعلمة دالة وأنها بديهية بما يكفي لاستخدامها وليس الأمر كما لو أن Mocha يتم تغذيتها في نوع من التجريد الآخر الذي يمكن أن ينكسر مثل هذا "السحر") ؛ يمكن أيضًا استخدام كائن الخيارات هذا لتوفير العلامات و / أو أسباب الاختبار المعلقة ، وكلاهما ميزات مطلوبة (يتم ترك العثور عليها في قائمة مشكلات GitHub / مربع البحث في قائمة العلاقات العامة كتمرين للقارئ). سوف أعترف بالتعاطف (حتى لو كان من الممكن التغلب على غيابهم ، فهناك مزايا للشيء الحقيقي على الحلول البديلة).

ScottFreeCode أنا أوافق بالتأكيد على done لا أحب استخدامه أيضًا ، كنت فقط أعلق على الحاجة إلى وضع السياق أولاً مقابل الأخير واستخدام المثال المذكور أعلاه المقدم من boneskull.

أنا فقط أحب خيار المرور في السياق أو ضبط بعض التبديل على mocha لتنفيذ es6.

في هذه الأثناء ، أقوم فقط بتغليف أوصاف الاختبار القليلة التي تتطلب اختلافات في المهلة في استدعاء وظيفة derpy-looking ().

لقد وجدت حلاً لحالة الاستخدام حيث يتم إرجاع الوعد إلى mocha من وظيفة السهم التي تحتاج إلى مهلة مخصصة ، والتي أريد مشاركتها في حال وجدها الآخرون مفيدة.

بإضافة الوظيفة التالية when المحددة أدناه في إعلان اختبار مثل: it('does something', when(() => someFunctionReturningAPromise, customTimeout)) يمكن ضبط مهلة mocha دون التخلي عن وظائف السهم.

وبالمثل ، ونظرًا لأننا نعمل فقط مع الوعود ، يمكننا إعادة استخدام المعلمة الأولى للاختبار واجتياز السياق بدلاً من رد الاتصال المنجز: it('can access the mocha test context', when(testContext => someFunctionThatNeedsContext(testContext))

const when = (lambda, timeout) =>
  function() { // return a plain function for mocha to bind this to
    this.timeout(timeout || this.timeout() || 1000)
    return lambda(this)
  }

بعض حالات الاختبار لتوضيح:

const delay = timeout =>
  new Promise((resolve, reject) => setTimeout(resolve, timeout))

const deject = timeout => // similar to above, but a delayed reject
  new Promise((resolve, reject) => setTimeout(reject, timeout))

describe('mocha testing', () => {
  context('with only arrow functions', () => {
    context('tests that do not time out', () => {
      it('passes fast', when(() => delay(10), 100))
      it('does not usually time out', when(() => delay(2000), 2010))
    })
    context('tests that will time out', () => { // these should fail if the 'when' function works properly
      it('times out fast', when(() => delay(1000), 10)) // will fail in 10ms
      it('times out', when(() => delay(1000), 1000)) // will fail in about 1000ms
    })
    context('tests that will reject', () => { // this shows the when function works as expected when a test rejects
      it('fails fast', when(() => deject(10), 100))
    })
  })
})

@ astitt-ripple نعم ، أو تكتب ببساطة function () {} ... Wtf؟

طيب لوكا ، لدغة سيئة. :-)

الفرق مع وظيفة السهم ، يمكن تخطي العودة. في
إعداد نوع es6 ، يمكن أن يكون هذا بالفعل نمطًا شائعًا للوعد "إذن"
السلاسل.

مع كتلة وظيفة ، كما تقترح ، وبقدر ما أعرف ، عودة
يجب أن يكون الوعد صريحًا. الحد الأدنى لوظيفة الاختبار القائمة على الوعد
{...} خاطئ ، يجب أن يفي الاختبار دائمًا بوعده ، لذا فهو الحد الأدنى
التبسيط الصالح هو في الواقع: دالة {عودة ...}. وإلا فإن
يعود الاختبار غير محدد إلى المخاوي وليس الوعد الذي تم إرساله ... و
كاتب الاختبار لديه وقت سيء.

إذا كانت معظم التعليمات البرمجية في قاعدة البيانات هي بالفعل وظائف السهم من الوعد
و / أو أسلوب برمجة وظيفي ، يمكن أن تبدو إضافة وظيفة إرجاع
تتعارض. نموذج "متى" المقترح متاح بدلاً من ذلك لمن
تفضل السهام وأسلوب وظيفي أكثر من الوظيفة التقليدية
رد الاتصال أو وظيفة العودة الأنماط. إنه أكثر إيجازًا ، ويتناسب مع
decribe Context it dsl نتفق جميعًا على أننا نحب كتابة الاختبارات ، مع أخذها في الاعتبار
حساب الوعد تجريد البرمجة غير المتزامن يعالج جافا سكريبت بذلك
حسنا. كما أنها أقصر من الوظيفة + العودة ، حتى بدون تجعيد الشعر لدينا:
عندما (() => ...).

ربما لم يكن هذا هو النمط المفضل لهذا المشروع ، وأنا أفهم ذلك ، و
أنا لا أقترحه كتغيير للمشروع. ربما حتى
اللوم كما يوحي wtf الخاص بك. هذا جيد. يجب أن تعمل موكا مع
js ودية قبل fp. التوافق مع الإصدارات السابقة هو مصدر قلق من الدرجة الأولى. الذي - التي
أيضا منطقي.

هذا خيط طويل ومعقد ، وهذا مخرج واحد. واحد لطيف
الشيء حول جافا سكريبت هو أنه لا يجب أن يكون هناك طريقة واحدة أو أسلوب واحد
انجاز الامور. نحن لسنا مضطرين للاتفاق على الاسلوب على الاطلاق. وظيفيا
بالحديث ، فإن رسالتي السابقة تمنح الناس طريقة لاستخدام السهام والوعود
باستمرار ومع اختبار dsl ، دون التخلي عن الوصول إلى المخاوي
السياق ، بطريقة ودية البرمجة النظيفة والوظيفية التي لم تفعل ذلك
تم اقتراحه مسبقًا.

شكرا.

إذا كانت معظم التعليمات البرمجية في قاعدة البيانات موجودة بالفعل ... أسلوب برمجة وظيفي ...

... ثم استخدام this.mutatingMethod(currentConfiguration) لإعداد السلوكيات ، خاصةً لوظيفة (أو بالأحرى روتين فرعي) يتم تنفيذها بالفعل ، هو طريقة أكثر تناقضًا من الاضطرار إلى كتابة return (وهو مجرد بناء جملة) ، والمظهر غير المتسق من شأنه أن يجعل هذا الواقع أكثر وضوحًا بدلاً من تقديم التناقض في الواقع.

(لا تفهموني خطأ ، أنا سعيد جدًا بارتفاع شعبية أفكار البرمجة الوظيفية في JS ؛ لكن بناء الجملة function / return مقابل => هو ليس ضروريًا في الواقع للبرمجة الوظيفية ، فقط مسألة ما يبدو أنظف في هذا النموذج ، في حين أن المفاهيم الأخرى مثل النقاء والإعلان مقابل الضرورة ضرورية في الواقع. سيكون من الرائع أن يكون لديك عداء اختبار كان ، بدلاً من ذلك ، أكثر فاعلية في سلوكها / دلالاتها ، وعند هذه النقطة من المحتمل أن يكون التبديل إلى وظائف السهم تافهًا ...)

أتفق معك في أن هذه المهلة هي طفرات وتقطع عن نموذج البرمجة الوظيفية. بالطبع إنه غير متسق تمامًا. في الوقت الحالي ، هل هناك أي طريقة أخرى للإعلان عن مهلة مخصصة لكل اختبار بخلاف this.timeout؟

في التطبيق الحالي لـ mocha ، يبدو من الضروري الهروب مرة أخرى إلى نموذج الضرورة / الطفرات ، أو التخلي عن الإعداد لكل مهلات اختبار. واحد او الاخر.

في التجريد أعلاه when ، المهلة هي المعلمة الثانية لـ when ، مما يسمح لنمط وظيفي بالبقاء على مستوى الاختبار. إنه يخفي هذا الهروب الحتمي من وضع FP إلى البرمجة الإلزامية ، ولكنه يفعل ذلك في مكان واحد. كما أنه يمنح وظائف السهم إمكانية الوصول إلى سياق mocha ، وهو أمر غير ممكن بدون كسر اصطلاح معلمة وظيفة الاختبار. لذلك من المحتمل أن يحل بعض المشكلات لبعض مستخدمي هذا المشروع (بناءً على تاريخ هذه المشكلة) في غضون ذلك حتى يستكشف شخص ما فكرة عداء الاختبار الخاص بك.

أيضا من فضلك لا تفهموني خطأ أيضا. لا أعتقد أن البرمجة الوظيفية سوف تحل محل البرمجة الحتمية / الطفرية المشتقة من آلة تورينج بالكامل. على سبيل المثال ، في كل حالة تقريبًا ، في وقت تشغيل JS ، يتم تفسير الكود ، سواء أكان وظيفيًا أم لا ، في النهاية بواسطة برنامج مكتوب بأسلوب الأمر الأكثر تقليدية (ربما c ++ ، ولكن ليس بالضرورة) ، يعمل على نظام تشغيل مكتوب أيضًا حول الطفرات والأفكار الحتمية (ربما ج). الذاكرة هي مورد ثابت ، وهياكل البيانات غير القابلة للتغيير هي كذبة يخبرنا بها وقت التشغيل. هذا النموذج الضروري بشكل أساسي هو الوضع الافتراضي في الحوسبة ، وهو موجود ليبقى. لكن هذا لا يعني أن البرمجة الوظيفية لا يمكن أن تتعايش فوقها. وإذا كان الأمر كذلك ، فمن المحتم أن ينزل كود FP إلى النموذج الأساسي من وقت لآخر. لا أعتقد أن هذا يعني أننا نرفع أيدينا ونقول كل بناء الجملة ، ونسمح فقط باستخدام الوظيفة / العودة.

في الواقع ، يمكننا القيام ببرمجة وظيفية في لغة C مع منح قدر معين من التفاوت مع التفاصيل ، تمامًا كما أنه من الصحيح أنه يمكنك القيام ببرمجة وظيفية باستخدام دالة / عودة بدلاً من وظائف =>. فقط لا تنسى أن تعود بوعدك. يستغرق FP in C قدرًا صغيرًا من الكتابة ، وهو بعد كل شيء مجرد بناء جملة ... / s

في نهاية اليوم ، تقربنا وظائف السهم تدريجياً من طريقة عملية وعملية للعمل في نموذج حساب لامدا ، بلغة شائعة. تُحدث إزالة هذه الأحرف الإضافية فرقًا بسيطًا ولكنه مهم. لا يزال هناك العديد من القيود العملية ، ولكن العديد منها قابل للحل ، والموضوع المطروح هو أحدها.

على أي حال. سأستخدم وظيفة المساعد المقترحة ، ويمكن للآخرين استخدامها الآن. إنني أتطلع إلى حل الاختبار الخاص بك ، ولكن في الوقت الحالي ، لا أعرف ما إذا كان سيكون مثمرًا بشكل خاص لمواصلة محاولة إقناع بعضنا البعض بآرائنا حول ما هو بناء الجملة المهم أم لا ، كما لو كان هناك طريقة واحدة. أنا أحب السهام وتحب الوظائف. لم أر حجة مقنعة تغير وجهة نظري. أنا منفتح على أحد ، ولكن كان من الأفضل التفكير في الأمر أكثر من الهزات في الركبة مثل: "فقط استخدم الوظيفة ، wtf" أو "لا يزال بإمكانك القيام بـ fp باستخدام _syntax_ أكثر تفصيلاً".

قم بحل المشكلة بطريقة أخرى ، وبعد ذلك لا يحتاج أحد إلى استخدام when . قال ناف. :-)

لا أعتقد أن هذا يعني أننا نرفع أيدينا ونقول كل بناء الجملة ، ونسمح فقط باستخدام الوظيفة / العودة.

أنا أحب السهام وتحب الوظائف.

... كان من الأفضل التفكير فيه أكثر من نفضات الركبة مثل: ... "لا يزال بإمكانك فعل fp مع بناء جملة أكثر تفصيلاً".

هذا إلى حد كبير عكس ما قلته ، على الرغم من - كنت أذهب إلى حقيقة أن وظائف الأسهم التي لا تزال تستخدم this لن تكون FP في المقام الأول ، ستكون OO مع وظائف السهم ( معكوس FP مع وظائف JS التقليدية). بعبارة أخرى ، بعيدًا عن كونه مجرد بناء جملة مختلف ، فإن المشكلة الحقيقية هي أن هناك عدم توافق أعمق في النموذج من مجرد عدم توافق بناء الجملة (كما تم تصميم Mocha حاليًا على أي حال).

أنا متأكد تمامًا من أنه من الممكن إنشاء واجهة بديلة أعلى Mocha لاستبدال this تمامًا بالمعلمات. أريد فقط أن أوضح أنه إذا كنت تريد الذهاب إلى FP في كتابة الاختبارات ، فسيتعين عليك القيام بأكثر من مجرد التوصل إلى طريقة لتمرير وظائف Mocha this إلى وظائف السهم. أنا جزيلا على ارتفاع لهذا النوع من التحدي، ولكن. ؛ ^)

(هناك أيضًا العديد من سلوكيات Mocha الأخرى التي تتسم بالحالة أو العالمية أو - الأسوأ - كلاهما ، ولكن ليس لدي الوقت في الوقت الحالي للتوصل إلى طريقة مختصرة لإدراجها في القائمة. إذا سبق لك أن رأيت المشكلات المتعلقة بتشغيل Mocha أكثر من مرة ، هذا مثال عليها ، رغم ذلك.)

في الوقت الحالي ، هل هناك أي طريقة أخرى للإعلان عن مهلة مخصصة لكل اختبار بخلاف this.timeout؟

لسوء الحظ ، أنا متأكد تمامًا من عدم وجود ذلك ؛ من أعلى رأسي ، يبدو اقتراح قبول معلمة إضافية لـ it والتي ستكون خريطة قيمة مفتاح (ككائن JS) لإعدادات التكوين بمثابة حل مستقبلي لائق في Mocha ، إذا كان أي شخص يريد ذلك حاول تنفيذه.

في الوقت الحالي ، هل هناك أي طريقة أخرى للإعلان عن مهلة مخصصة لكل اختبار بخلاف this.timeout؟

لسوء الحظ ، أنا متأكد تمامًا من عدم وجود ذلك ؛

شكرا لتأكيد هذه التفاصيل. هذا يعزز النقطة التي كنت أثيرها.

بعيدًا عن رأسي ، يبدو اقتراح قبول معلمة إضافية لها من شأنها أن تكون خريطة قيمة مفتاح (ككائن JS) لإعدادات التكوين بمثابة حل مستقبلي لائق في Mocha ، إذا أراد أي شخص محاولة تنفيذه.

+1 لحل أكثر عمومية.

من خلال ما يمكنني قوله ، يبدو أنه من العملي تمرير معلمة واحدة. ادمج this مع رد الاتصال done (بحيث يصبح this دالة). بعد ذلك ، قم بتشغيل كل اختبار محاطًا بوعد (حسنًا ، اثنان في الواقع ، واحد للتعامل مع المهلة ، والآخر لإجراء الاختبار فعليًا) ، بغض النظر عن عدد المعلمات (الخروج عن كيفية عمله اليوم). يمكنه بعد ذلك التحقق من أن نتيجة الوظيفة كانت وعدًا أم لا. إذا لم يكن الأمر كذلك ، فاتصل بـ done بعد عودة الدالة المتزامنة لإنهاء الاختبار. إذا كانت نتيجة الوظيفة عبارة عن وعد بدلاً من ذلك ، فانتظر حتى يتم حلها (أو رفضها). في حالة حدوث المهلة ، أوقف الاختبار (كما كان من قبل). في حالة تمكن الاختبار من استدعاء done وإرجاع الوعد أيضًا. يتم استدعاء أي منهما قبل الحل ، وفي هذه الحالة يجب أن تنتظر المخا الوعد ثم تفشل في الاختبار لوجود تسلسل إكمال غامض. أو يتم استدعاء "تم" في وقت ما بعد الحل ، وفي هذه الحالة بطريقة ما يجب أن يفشل الاختبار بأثر رجعي - أو تشير المشكلة إلى طريقة أخرى معقولة. آسف ، هذا كثير من الضربات العريضة ، لكن هذا هو فهمي الخارجي لما تحاول موكا القيام به والمراوغات التي تصطدم بها. ما هي الاعتبارات الأخرى التي قد تمنع هذا من أن يكون حلاً عمليًا؟

إذا كنت تريد الذهاب إلى برنامج FP في اختبارات الكتابة ، فسيتعين عليك القيام بأكثر من مجرد التوصل إلى طريقة لتمرير Mocha إلى وظائف السهم

متفق عليه. هناك تغيير واضح في الانتقال إلى نموذج حسابي مختلف ، وبالإضافة إلى ذلك ، فإن جافا سكريبت هي نظام بيئي معقد يتطلب الكثير في الاعتبار. في حالة الاستخدام الخاصة بي ، ومع ذلك ، فإن تعيين المهلة من وقت لآخر (مثل أن تكون أكثر دقة بناءً على بعض الحسابات بدلاً من قيمة افتراضية ثابتة) ، هي المشكلة الملموسة الوحيدة التي واجهتها في كتابة اختبارات FP باستخدام Mocha (حتى الآن على الاكثر). وهو أمر عظيم. : +1:

بعد قولي هذا ، أود أن أعرف ما الذي تراه أيضًا كعقبات وشيكة تتعلق على وجه التحديد بـ Mocha (على عكس ما قد تعنيه اختبارات الكتابة في FP بشكل عام).

هذا إلى حد كبير عكس ما قلته ، مع ذلك

أنا آسف إذا أخطأت في التوصيف أو أسيء فهمي. بالنسبة إلى الكثير مما كتبته ، لست متأكدًا من أنني كنت أتحدث كما هو مقصود أيضًا ، بناءً على الردود. وهذا أمر مؤسف ، لأنني أعتقد أنه إذا وصلنا إليه ، فربما نكون قد توصلنا إلى اتفاق وثيق جدًا حول الشكل الذي يجب أن يبدو عليه FP في _theory_. ومع ذلك ، يبدو أننا نختلف هنا بشأن الشكل الذي قد يبدو عليه التخفيض العملي لـ _الممارسة_ في الإصدارات الحالية من Mocha اليوم ، على الأقل بالنسبة لبعض المستخدمين / حالات الاستخدام. لذلك لست متأكدًا تمامًا من المشكلة الرئيسية المتعلقة بوظيفة الإضافة المقترحة التي اقترحتها ، من جانبك.

(تم الاقتباس والرد بالترتيب ، ولكن يمكن القول إن الأشياء الأكثر أهمية تأتي لاحقًا وليس قبلها).


من خلال ما يمكنني قوله ، يبدو أنه من العملي تمرير معلمة واحدة. ادمج هذا مع رد الاتصال المنجز (بحيث تصبح هذه وظيفة). ثم ... ما هي الاعتبارات الأخرى التي قد تمنع هذا من أن يكون حلاً عمليًا؟

إذا كسرنا التوافق مع الإصدارات السابقة ، فهناك طريقة تصميمات أبسط يمكننا التبديل إليها.

إذا حافظنا على التوافق مع الإصدارات السابقة ، فيجب أن يمر كلا الاختبارين وليس مهلة:

it("runs immediately", () => {
  // call functions and assert whatever
})
it("runs asynchronously", doneWithSomeOtherName => {
  setTimeout(() => {
    // call functions and assert whatever
    doneWithSomeOtherName()
  }, 100)
})

نرحب بمحاولة التوصل إلى بعض الأمثلة على الكود لإثبات خلاف ذلك (على الرغم من أنني أقترح التركيز على الاقتراح في نهاية هذا التعليق بدلاً من ذلك) ، لكنني متأكد تمامًا من عدم تمكن أي تصميم من القيام بذلك و أيضًا ، اجعل هذا الاختبار يجتازه وليس مهلة:

it("looks just like an asynchronous test with a different name for `done`, but never tells Mocha it's done", context => {
  context.configureByMutation("some value")
  // call functions and assert whatever
})

لكن أيضًا ، لاحظ الطفرة هناك. المزيد عن هذا أدناه.


في حالة الاستخدام الخاصة بي ، ومع ذلك ، فإن تعيين المهلة من وقت لآخر (مثل أن تكون أكثر دقة بناءً على بعض الحسابات بدلاً من قيمة افتراضية ثابتة) ، هي المشكلة الملموسة الوحيدة التي واجهتها في كتابة اختبارات FP باستخدام Mocha (حتى الآن على الاكثر). وهو أمر عظيم.

: +1 :!


بعد قولي هذا ، أود أن أعرف ما الذي تراه أيضًا كعقبات وشيكة تتعلق على وجه التحديد بـ Mocha (على عكس ما قد تعنيه اختبارات الكتابة في FP بشكل عام).

أعتقد أنني ربما لم أكن أوصل هذا التركيز تمامًا ... بشكل مفاجئ ، لذلك اسمحوا لي أن أرى ما إذا كان بإمكاني أن أغليها قليلاً. (آسف أيضًا إذا كان أي من هذا قد ظهر على أنه معادٍ ؛ فمن المؤكد أنه ليس المقصود أن يكون كذلك ، على الرغم من أنني أعترف بمحاولة تغيير العقليات هنا.) قاعدة رموز Mocha هي جزء كبير من التسلسل الهرمي للطبقة وأسلوبها. "اتجاه الكائن" (وهناك العديد من المشكلات أو المشكلات المحتملة التي تواجه Mocha والتي أعتقد أنها تنخفض إلى حالتها القابلة للتغيير) ، ولكن هذا لا يؤثر بشكل عام على كود الاختبار الخاص بك إذا كان كل ما تفعله هو كتابة الاختبارات والسماح لـ Mocha بتشغيلها . يمكنك أن تفعل أشياء غريبة مع تكوين تحور بد موكا في:

it("imperatively sets the timeout multiple times", function(done) {
  this.timeout(5000)
  var context = this
  setTimeout(function() {
    context.timeout(1000)
    setTimeout(done, 500)
  }, 4000)
})

... لكن ليس عليك ذلك. كما هو الحال مع العديد من عناصر البرمجة وظيفيًا في اللغات غير الوظيفية: فقط لا تسيء استخدام الأشياء الضرورية.

(هناك أيضًا حجة يجب تقديمها بأن الاستثناءات غير نقية ، لكنني لست مقتنعًا بعد بأن هذا صحيح بالنسبة للاستثناءات التي يتم طرحها بناءً على المدخلات - والتي يمكن اعتبارها شكلاً آخر من أشكال الإخراج. لذلك قد يقول البعض ذلك باستخدام التأكيدات هذه الرمية لا تعمل ، لكنني لن أعالجها في هذه المرحلة.)

(جزء مهم هنا :) ما أحاول الوصول إليه هو ، أننا نبحث في إمكانية إضافة تعقيد إلى قاعدة بيانات معقدة بالفعل ، أو إجراء تغيير غير متوافق مع الإصدارات السابقة. نحن بحاجة إلى تبرير لأي من هذه الأشياء. إذا كان التبرير هو "جعل الاختبارات أكثر فاعلية" ، فهذا جيد (في كتابي على أي حال). قد يكون التصميم الذي يجعل الاختبارات أكثر فاعلية يستحق العناء (اعتمادًا على حجم المشكلة). ولكن إذا كنت تقصد بـ "جعل الاختبارات أكثر فاعلية" "جعل وظائف السهم تغير الأشياء" ، أي "تجعل وظائف السهم أقل فاعلية" ، فهذا يضعف الحالة كثيرًا (إذا لم يكن مجرد تناقض ذاتي). بشكل كامل: لا أعتقد أن جعل الاختبارات تبدو أكثر فاعلية (نظيفة كما تبدو وظائف السهم!) مع الاحتفاظ بالجزء الوحيد من الطفرة المعنية ، مهما كان ذلك الجزء صغيرًا في البداية ، يكاد يكون تبريرًا مقنعًا كما هو الحال في الواقع سيكون التخلص من هذا الجزء

ربما لم يكن من المفترض أن أبتعد بعيدًا عن هذا الظل ؛ انظر أدناه فيما يتعلق بالحلول. 😸


لذلك لست متأكدًا تمامًا من المشكلة الرئيسية المتعلقة بوظيفة الإضافة المقترحة التي اقترحتها ، من جانبك.

(جزء مهم أيضًا هنا :) حسنًا ، أحب الجزء الذي يأخذ فيه timeout كمعامل بدلاً من استدعاء طريقة ، في الواقع! إذا كان بإمكانك التوصل إلى طريقة لتعميم ذلك على بقية طرق تكوين Mocha (هناك الكثير منها - وبعضها ينطبق على الاختبارات المتزامنة إذا كنت أتذكر ذلك بشكل صحيح ، وبالتالي لا يمكننا إضافة نفس الأساليب مثل الخصائص على done والسماح للأشخاص بكتابة اختبارات غير متزامنة يمكنها استدعاء التهيئة من خلال done ، لكني استطرد) ، فأنا بالتأكيد أريد إلقاء نظرة عليها. على أقل تقدير ، قد نرغب في تقديم توصية ، وقد نتمكن حتى من اعتماد التنفيذ في it عند تمرير معلمة ثالثة (أو شيء من هذا القبيل ، ربما it.configured أو it(...).configured(...) إذا كنا لا نريد المزيد من خدع عدد المعلمات ...) - والذي أعتقد أنه سيكون حلاً متوافقًا مع الإصدارات السابقة والذي يعالج الطفرة الأساسية / المسألة الحتمية ويحصل على دعم وظيفة السهم "الحق الطريقة "(ما أجادله على هذا النحو على أي حال): لأنه يناسب السلوك الجديد. أعتقد أن ما كان يجب أن أقوله ، بدلاً من البحث عن this في الحل البديل ، هو: دعنا نوسع جزء المعلمة منه!

أقسم أنني قرأت في مكان ما يمكنك أن تفعل شيئًا كهذا:

describe('a slow thing', () => {
 // test code...
}).timeout(5000);

الذي لا يغير عقد المعلمة للوظيفة المقدمة. الآن لا يمكنني العثور على أي إشارة إلى أي شيء من هذا القبيل ، لذا ربما تخيلته للتو.

@ thom-nic هذا يعمل! أعتقد أنه من المنطقي لأن جميع وظائف mocha تعيد سياقها

return this;

إنه يعمل معي عند استبدال نموذج وظيفة السهم بالوظيفة العادية

وظيفة() { ..... }

مرحبا يا رفاق. أعتذر عن الذهاب إلى الظلام بعد إثارة النقاش مرة أخرى في أغسطس ، لقد كنت مشغولًا للغاية وقد أكملت / انتقلت من هذا العمل في الغالب.

أقدر الرد المفصل حول حالات الاستخدام المختلفة وكيف يصعب تنسيقها معًا. كان هذا هو العرض الأكثر إيجازًا للإعدادات المختلفة التي يجب أن يدعمها mocha التي قرأتها. لذا أشكرك على وقتك في ذلك.

إذا نظرنا إلى الوراء ، من الواضح أنني يجب أن أفرط في التأكيد على الوصول إلى سياق المخاوي ( this ) ، عندما كان هذا الجانب أكثر ملاءمة بعد التفكير. لم أكن أدرك مدى سهولة جذب الانتباه بعيدًا عما كنت أحاول فعله بالفعل: والذي كان يستمتع ببعض المرح عن طريق إضافة ملحق مؤقت ( when ) إلى اختبار dsl لتبسيط الاستخدام لمرة واحدة تعديلات المهلة (بالإضافة إلى التخلص من خطأ شائع لأسلوب معين من الاختبارات ، والذي سأوضحه أدناه). كان إرجاع this مجرد شيء ممتع آخر فكرت في إضافته ، وكانت الفكرة الرئيسية (ومن هنا جاء الاسم when ) التعامل مع الحالات التي تتطلب مهلات مختلفة عن المعتاد.

من الواضح ، إذا كنت أرغب في الوصول إلى السياق المرتبط ، فيمكنني ببساطة استخدام function مباشرة كما اقترح الكثيرون ، بدلاً من رفعه باستخدام غلاف. هذه ليست القضية 😄 لا يفوتني كيف قد يبدو ذلك غريباً في ظاهره. آمل أنه ربما يتم الانتهاء من الصورة إذا عرضت كيف كنت أقوم بإعداد بعض الاختبارات التي قادتني إلى هذا المسار لتبدأ. لأكون واضحًا ، أنا لا أحاول بيع أي نمط معين هنا ، استخدم ما يناسبك. هذا ما نجح معي

نعم
أولاً ، ابدأ بافتراض أننا نختبر بعض الإعدادات التي تؤدي شيئًا واحدًا بشكل أساسي ، ولكنها ستفعل ذلك لمجموعة واسعة من المدخلات ، ولذا يجب علينا اختبار هذا الشيء في مجموعة من السيناريوهات لضمان صحة المخرجات . ومع ذلك ، نظرًا لأن كود التطبيق ذي الصلة "يفعل شيئًا واحدًا" ، فإن إجراء الاختبار الأساسي دائمًا ما يكون هو نفسه. لا أرغب أيضًا في تكرار / تغيير جسم الاختبار دون داع ، لأن ذلك يبطئ من سرعة إضافة المزيد من حالات الاختبار للمدخلات الجديدة ، وفي النهاية ستصبح الصيانة غير معقولة.

لذلك بدلاً من ذلك ، نكتب وظيفة عامة بما يكفي لبدء رمز التطبيق مع أي مدخلات مدعومة ، وتنفيذ إجراء الاختبار ، ثم تأكيد النتائج ... أضف ذلك في حالتي كنت أعمل مع تجريد الوعد (لأسباب ذلك سأترك) ، لذلك يجب أن تعيد وظيفة إجراء الاختبار المعمم هذا الوعد ، ثم السلسلة. الخبز والزبدة es6 نوعًا من الأشياء ، جيد جدًا حتى الآن.

الآن تأتي سيناريوهات الاختبار ، نظرًا لأننا قمنا بتجميع كل شيء في وظيفة إجراء الاختبار لدينا ، فإن حالات الاختبار تحدد المدخلات بشكل فعال وتستدعي الوظيفة.

لذلك ربما أكتب مجموعة من الاختبارات مثل هذا ، وكل شيء يبدو أنه يعمل:

it('does something', function() {
  testProcedureFunction('something','1')
})

إذا كنت تتابع عن كثب ، فربما تكون قد لاحظت بالفعل أن هذا المثال به خطأ. إنه يفتقد إلى return ، وبما أن testProcedureFunction مبني على وعود (يقصد التورية) ، فإنه سينتقل دائمًا بغض النظر عما إذا كانت التأكيدات في النهاية تمر أو تفشل. هذا خطأ ، ويمكن أن يكون خفيًا للغاية لتعقبه في بعض الأحيان. للتوضيح ، اعتمادًا على كيفية كتابتنا testProcedureFunction وكيفية كتابة التطبيق ، دعنا نقول أن هناك بعض التعليمات البرمجية المتزامنة في البداية ، والتي تنفجر بدلاً من تأكيدات نهاية الاختبار ، قد تفشل حالة الاختبار - مما يقودنا أعتقد أن كل شيء على ما يرام.

يجب أن يبدو الاختبار بالطبع هكذا حقًا مع عودة:

it('does something', function() {
  return testProcedureFunction('something','1')
})

الآن أعلم أن هذا الاختبار سيكون سطرًا واحدًا في معظم الحالات. في الواقع ، ستكون كل حالة عبارة عن سطر واحد ، باستثناء عندما تكون المدخلات تتطلب مهلة أكبر. الآن من بين الاختلافات بين دوال js الكلاسيكية والسهام ، هناك جانب معين من وظائف السهم مفيد هنا: وظيفة سهم عبارة واحدة لها عائد ضمني عند حذف الأقواس. إذا كان الاختبار يستخدم => ... بدلاً من كتابة function {...} ، فيمكنني بسهولة مسح هذه الحالات بحثًا عن السهم وعدم وجود الأقواس المتعرجة ، وسرعان ما استنتج أنه لا يمكن أن يكون لديهم هذا return المفقود مشكلة

مثل ذلك:

it('does something', () => testProcedureFunction('something','1'))

الآن ماذا لو استغرقت إحدى هذه الحالات وقتًا أطول من غيرها! يمكننا بالطبع ضبط المهلة على النحو التالي:

it('does something slow', function() {
  this.timeout(10000)
  return testProcedureFunction('somethingSlow','2')
})

أو ربما يرتكب شخص ما خطأ ويفعل هذا أولاً (وهذا لا يعمل بالطبع):

it('does something slow', () => {
  this.timeout(10000)
  return testProcedureFunction('somethingSlow','2')
})

لكننا الآن عدنا إلى حيث بدأنا ، يحتوي قاعدة الشفرة على نمط جاهز للتكرار ، وهو عرضة لخطأ الإرجاع المفقود (إما عن طريق مستقبلي ، أو عن طريق الشخص التالي لإضافة ميزة - النقطة المهمة هي أنها سهلة ارتكاب خطأ ، فقد يمر مرور الكرام ، وقد يكون من الصعب تعقبه). تعمل الدالة when حل هذا الأمر ، وتتيح لنا استخدام الأسهم باستمرار مرة أخرى:

it('does something slow', when(() => testProcedureFunction('somethingSlow','2'), 10000))

(لاحظ، لم أكن قادرة على الحصول على .timeout(5000) دوت-تسلسل اقتراح أعلاه للعمل، قد يكون بسبب إصدار المخاوي كنت بحاجة إلى استخدام، وأنا لا أتذكر بعد الآن، سيعطي أن محاولة!)
(ملاحظة 2 ، لاحظ أن استخدام when لا يستخدم خدعة رفع المعلمة this - لقد كانت مجرد فكرة لاحقة).

ربما هناك نصوص يمكنها تحديد أخطاء العودة مقابل الوعد (أو ربما بشكل أكثر واقعية ، فرض بيان إرجاع مع rhs لكل دالة). ومع ذلك ، لم يكن هذا خيارًا في ذلك الوقت ، بالإضافة إلى أنني أعتقد أن بناء جملة السهم يظهر بشكل أقصر وأجد أنه (شخصيًا / شخصيًا) أسهل في القراءة والعمل معه ، مما أدى إلى إبعاد الميزان عن function .

لذلك هناك لديك.

لا أعرف ما إذا كان سيكون لدي وقت للرد مرة أخرى في أي وقت قريب ، لذلك آمل أن يكون ذلك على الأقل مفيدًا وواضحًا ، وربما حتى يطرح بعض الجدل الدائر حول "الوصول إلى سياق المخاوي من الأسهم" بالكامل إلى سرير.

أخيرًا ، نظرًا لأنني وجدت الوظيفة مقابل => مربكة لفترة طويلة ، فسوف أسقط هذا الرابط في حالة عدم وضوح هذا الرابط لأي شخص يقرأ عرضًا سبب عدم تمكن الأسهم من الوصول إلى this . لقد كان أوضح شرح للوظائف مقابل الأسهم الذي وجدته ، وكان ما ساعدني أخيرًا على فهم الاختلافات جيدًا بما يكفي لاستخدامها بثقة كاملة.

https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/

@ thom-nic يعمل على it ، لكن ليس على describe .

describe('my test suite', () => {

  it('test case 1', () => {
    // ...
  }).timeout('10s');  // Works on `it`. This test case doesn't timeout

  it('test case 2', () => {
    // ...
  });  // This test case timeouts.

}).timeout('10s');  // Doesn't work on `describe`. Tests are already created when runs to here.

@ thom-nic ، يمكنك استخدام صيغة الوظيفة العادية

describe('my test suite', function() {
this.timeout(n);

...
}

أي شخص يشتكي من هذا لا يفهم وظائف الأسهم.

وظائف الأسهم ليست شيئًا جديدًا من ES6 من المفترض أن يحل محل function () {} الكلاسيكي. الغرض الوحيد من وظائف السهم هو أنه يرث this من والده ، حيث function () الكلاسيكي يمتلك this .

نعم ، حتى عند استخدام بناء جملة ES6 الكامل ، لا يزال يتعين عليك استخدام function () إذا كنت تريد استخدام this في السياق الصحيح لوظيفتك. يجب أن تستخدم كلاً من function () و () => في تطبيق ES6 اعتمادًا على ما تحاول القيام به.

this.timeout() لا يعمل مع it('....', () => { ... }) لأن رد الاتصال يرث this من الأصل describe() ، حيث this.timeout() لا منطقيًا على هذا المستوى.

ألا تسمح لك وظائف lambda أيضًا بإرسال وسيطة واحدة تلقائيًا إلى الوظيفة دون الإعلان عنها في المكالمة؟

(بارام) => وظيفة
... ثم (وظيفة)

يمكن ربط الوظيفة () {} بـ "هذا" ولكن () => "مغلق في"

يجب أن تحل وظائف السهم يتوقع المتلقي "هذا" محددًا مسبقًا في نفس السياق الذي تم استدعاؤه منه ، (والاستفادة أيضًا من كتابة رمز أقل).

سأذهب إلى أبعد من ذلك لأقول لا تستخدم الدالة أبدًا () إلا إذا كنت تريد أن يكون "هذا" شيئًا مختلفًا عن "هذا" عند استدعائه.

Flamenco ...

ألا تسمح لك وظائف lambda أيضًا بإرسال وسيطة واحدة تلقائيًا إلى الوظيفة دون الإعلان عنها في المكالمة؟

لست متأكدًا من أنني أفهم _بالضبط _ كيف تضع ذلك.
بالنسبة إلى "إرسال الوسائط إلى الوظيفة" ، تعمل أسهم الدهون تمامًا مثل الوظائف العادية مع استثناء واحد: إذا كان لديك وسيطة واحدة بالضبط ، فيمكنك ترك الأقواس.

() => console.log("hi"); //zero arguments requires empty parenthesis
a => console.log(a); //you can optionally leave the parenthesis off for 1 argument
(a,b) => console.log(`${a} ${b}`); //2..n arguments requires parenthesis

ما كنت تحصل عليه هو أن الأسهم الدهنية تسمح لك بإرجاع قيمة عن طريق حذف الأقواس المتعرجة والكلمة الأساسية return طالما أن وظيفتك هي تعبير واحد.
لذلك إذا كان لديك ...

setTimeout(function(a,b) { doSomething(); return calculateSomething(a,b); }, 5000);

... وأردت تحويل ذلك إلى وظيفة سهم سمين ، فلن تكون قادرًا على هز الأقواس المتعرجة والكلمة الأساسية للعودة لأن جسم الوظيفة يحتوي على عبارات متعددة. ستفعلها هكذا ...

setTimeout((a,b) => { doSomething(); return calculateSomething(a,b); }, 5000);

إذا كنت قد بدأت بـ ...

setTimeout(function(a,b) { return calculateSomething(a,b); }, 5000);

... فأنت تتعامل مع وظيفة بهذه البساطة لدرجة أنها تعرض تعبيرًا واحدًا فقط ويمكنك استخدام ...

setTimeout((a,b) => calculateSomething(a,b), 5000);

هذا أصبح أسهل بكثير للقراءة!
لقد كتبت المزيد عن هذا في codefoster.com/levelup-arrays .

هناك العديد من أنماط الترميز المختلفة في JavaScript - من OOP إلى FP ، من أمان الكتابة الصارم إلى mixin / duck-typing. بالإضافة إلى ذلك ، هناك أنماط متقدمة في كل من هذه الأساليب (مثل حقن التبعية في معسكر OOP ، والكاري / أحادي في معسكر FP).

إذا كان نمط الترميز الخاص بك أقرب إلى FP حيث لا يتم استخدام this ويتم استخدام وظائف السهم لتقليل الصيغة المعيارية ، فإن الحاجة إلى الحفاظ على this هي تكلفة إضافية لأي اختبار متقدم (على سبيل المثال ، الاختبار المعتمد ، الإنشاء DSL).

يمكن لأي مطور متمرس أن يقوم فقط بالتغليف المسبق لإطار عمل الاختبار ليناسب أسلوب الترميز الخاص به ، ولكن هذا يعني أن إطار العمل أقل "خارج الصندوق". وهذا يترجم إلى عمل إضافي للترقية واعتماد المكونات الإضافية وإعداد مهندسين جدد.

تعجبني فكرة الواجهة البديلة bdd التي لا تستخدم this وبدلاً من ذلك تمرر ما يمكن أن يكون عادةً كائن السياق كمعامل إلى describe ، it وخطافات.

لكنها ليست سهلة التنفيذ ، IIRC. سيكون من الرائع رؤية محاولة بالرغم من ذلك.

أعلم أن هذا يدخل في نطاق الآثار الجانبية الخطيرة ، لكن ألا يمكنك التعامل مع معلمة التنفيذ أو السياق شيء من هذا القبيل؟

it("runs immediately", () => {
  // call functions and assert whatever
})
it("runs asynchronously", doneOrContext => {
  setTimeout(() => {
    // call functions and assert whatever
    doneOrContext();
  }, 100)
})



md5-b1fe6f00c87a2916712cf6a4df16e142



it("runs immediately using the parameter as a context", doneOrContext => {
  doneOrContext.configureByMutation("some value");
  // As well as changing config, also flags to Mocha that this test is treating the
  // parameter as a context object and is therefore not async.
  // Call functions and assert whatever
})



md5-b1fe6f00c87a2916712cf6a4df16e142



it("runs asynchronously using the parameter as a context", doneOrContext => {
  doneOrContext.configureByMutation("some value");
  doneOrContext.setAsync(); // Flags to Mocha that even though the parameter has been used as
  // a context object, the test is in fact asynchronous.
  setTimeout(() => {
    // call functions and assert whatever
    doneOrContext();
    // or doneOrContext.done()
  }, 100)
})

لقد استخدمت البرنامج النصي أدناه ولكني حصلت على نفس خطأ تجاوز المهلة.

مخطوطة:

وصف ("getBillingDetail" ، دالة غير متزامنة () {
this.timeout (55000) ؛
it.only ("تحقق من إعطاء اسم عمل صالح" ، وظيفة غير متزامنة (تم) {
this.timeout (55000) ؛
var نتيجة = await url.getBillingDetail ('12254785565647858') ؛
console.log (نتيجة) ؛
assert.equal (نتيجة ، صواب) ؛
}) ؛
}) ؛

خطأ: تجاوز المهلة 55000 مللي ثانية. بالنسبة للاختبارات غير المتزامنة والخطافات ، تأكد من استدعاء "تم ()" ؛ في حالة إعادة الوعد ، تأكد من أنه يحل.

لا تمرر رد نداء تم إلى وظيفة غير متزامنة

لقد أنشأت نموذجًا أوليًا لحل متوافق مع الإصدارات السابقة. في الوقت الحالي ، إنها وحدة منفصلة ، ولكن يمكن بسهولة دمج الوظائف في mocha المناسب.

https://github.com/papercuptech/mocha-lambda

طريقة سريعة

require('mocha-lambda')
// now a global '_tst' can be used where 'this' was before

describe('suite', () => {
  beforeEach(() => {
    _tst.answer = 42
  })

  it('provides "this" as "_tst"', function() {
    assert(this === _tst)
  })

  it('works', () => {
    assert(_tst.answer === 42)
    _tst.skip()
  })
})

للتسمية الصريحة (وتعمل مع TypeScript)

// if you were previously explicitly importing api (describe, it, etc.) from 'mocha',
// you will have to change to importing from 'mocha-lambda', until (or if) this
// gets merged into mocha proper
import ctx, {describe as d, it as i} from 'mocha-lambda'

d('suite', () => {
  // ctx() is a function that returns "this" as appropriate
  i('works using ctx()', () => {
    ctx().skip()
  })
})

import {Context} from 'mocha'
// ctx() can also rename global
ctx('t')
declare var t: Context
d('suite', () => {
  // ctx() is a function that returns "this" as appropriate
  i('works using renamed global', () => {
    t.skip()
  })
})

papercuptech الارتباط 404 غير موجود.

Woops .. كان الريبو الخاص. الآن عامة

ويمكن أيضا npm أنا mocha-lambda

aleung @ lineh-simplicity ، حل محله # 3485

شكرا.

لماذا الكثير من "السحر" الذي ينتج عنه في النهاية مشاكل؟ لما لا هذا ؟:

var mocha = require('mocha');

mocha.describe('foo', (suite) => {
  suite.timeout(100);

  suite.it('must love bar', () => ... );  
});

لا توجد كرات أرضية ، ولا سحر إشكالي ... ولكن فقط جافا سكريبت.

انظر @ thom-nic إجابة ونظيفة وفعلت الحيلة

أقسم أنني قرأت في مكان ما يمكنك أن تفعل شيئًا كهذا:

describe('a slow thing', () => {
 // test code...
}).timeout(5000);

الذي لا يغير عقد المعلمة للوظيفة المقدمة. الآن لا يمكنني العثور على أي إشارة إلى أي شيء من هذا القبيل ، لذا ربما تخيلته للتو.

حل @ thom-nic يعمل بالنسبة لي ، شكرًا!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات