এই উত্তরটি আন্দ্রেস কাবারেলের উত্তরের ভিত্তিতে তৈরি ।
তার সমাধানটি বাস্তবায়ন এবং বুঝতে আমার পক্ষে এত সহজ ছিল না, তাই আমি কীভাবে এটি কাজ করে তা আরও বিশদে এবং কিছু ক্ষতিগুলি এড়ানোর জন্য ব্যাখ্যা করব, আশা করি যে এটি ভবিষ্যতের দর্শকদের সহায়তা করবে।
সুতরাং, সমস্ত সেটআপের আগে:
আমি পরীক্ষার রানার হিসাবে কর্ম এবং পরীক্ষার কাঠামো হিসাবে MochaJs ব্যবহার করছি ।
স্কয়ারের মতো কিছু ব্যবহার করা আমার পক্ষে কাজ করে না, কোনও কারণে, যখন আমি এটি ব্যবহার করি, পরীক্ষার কাঠামোর ত্রুটি ছুঁড়ে ফেলে:
প্রকারের ত্রুটি: অনির্ধারিত সম্পত্তি 'কল' পড়তে পারে না
আবশ্যকজেগুলিতে অন্যান্য মডিউল আইডিতে মডিউল আইডির মানচিত্রের সম্ভাবনা রয়েছে । এটি এমন একটি require
ফাংশন তৈরি করতে দেয় যা গ্লোবালের চেয়ে আলাদা কনফিগার ব্যবহার করে require
।
এই বৈশিষ্ট্যগুলি কাজের সমাধানের জন্য এটি গুরুত্বপূর্ণ।
এখানে মক কোডটির আমার সংস্করণটি রয়েছে (অনেকগুলি) মন্তব্য সহ (আমি এটি বুঝতে সক্ষম হব আশা করি)। আমি এটিকে একটি মডিউলের অভ্যন্তরে আবৃত করেছি, যাতে পরীক্ষাগুলি সহজেই এটির প্রয়োজন হয়।
define([], function () {
var count = 0;
var requireJsMock= Object.create(null);
requireJsMock.createMockRequire = function (mocks) {
//mocks is an object with the module ids/paths as keys, and the module as value
count++;
var map = {};
//register the mocks with unique names, and create a mapping from the mocked module id to the mock module id
//this will cause RequireJs to load the mock module instead of the real one
for (property in mocks) {
if (mocks.hasOwnProperty(property)) {
var moduleId = property; //the object property is the module id
var module = mocks[property]; //the value is the mock
var stubId = 'stub' + moduleId + count; //create a unique name to register the module
map[moduleId] = stubId; //add to the mapping
//register the mock with the unique id, so that RequireJs can actually call it
define(stubId, function () {
return module;
});
}
}
var defaultContext = requirejs.s.contexts._.config;
var requireMockContext = { baseUrl: defaultContext.baseUrl }; //use the baseUrl of the global RequireJs config, so that it doesn't have to be repeated here
requireMockContext.context = "context_" + count; //use a unique context name, so that the configs dont overlap
//use the mapping for all modules
requireMockContext.map = {
"*": map
};
return require.config(requireMockContext); //create a require function that uses the new config
};
return requireJsMock;
});
সবচেয়ে বড় ফাঁদ আমি সম্মুখীন, যা আক্ষরিক আমাকে ঘণ্টা খরচ RequireJs কনফিগ তৈরি করা হয়। আমি এটি (গভীর) অনুলিপি করার চেষ্টা করেছি, এবং কেবল প্রয়োজনীয় বৈশিষ্ট্যগুলি (যেমন প্রসঙ্গ বা মানচিত্র) ওভাররাইড করব। এটা কাজ করে না! শুধুমাত্র অনুলিপি করুন baseUrl
, এটি সূক্ষ্ম কাজ করে।
ব্যবহার
এটি ব্যবহার করতে, এটি আপনার পরীক্ষায় প্রয়োজন, মক তৈরি করুন এবং তারপরে এটি পাস করুন createMockRequire
। উদাহরণ স্বরূপ:
var ModuleMock = function () {
this.method = function () {
methodCalled += 1;
};
};
var mocks = {
"ModuleIdOrPath": ModuleMock
}
var requireMocks = mocker.createMockRequire(mocks);
এবং এখানে একটি সম্পূর্ণ পরীক্ষা ফাইলের একটি উদাহরণ :
define(["chai", "requireJsMock"], function (chai, requireJsMock) {
var expect = chai.expect;
describe("Module", function () {
describe("Method", function () {
it("should work", function () {
return new Promise(function (resolve, reject) {
var handler = { handle: function () { } };
var called = 0;
var moduleBMock = function () {
this.method = function () {
methodCalled += 1;
};
};
var mocks = {
"ModuleBIdOrPath": moduleBMock
}
var requireMocks = requireJsMock.createMockRequire(mocks);
requireMocks(["js/ModuleA"], function (moduleA) {
try {
moduleA.method(); //moduleA should call method of moduleBMock
expect(called).to.equal(1);
resolve();
} catch (e) {
reject(e);
}
});
});
});
});
});
});
define
ফাংশনটি উপহাস করার জন্য আমি নোড.জেজে কিছু ক্রেজি ইভাল স্টাফ করছি । যদিও কয়েকটি আলাদা বিকল্প রয়েছে। আমি আশা করি একটি উত্তর পোস্ট করব যে এটি সহায়ক হবে।