প্রথমবার যখন থার্ড-পার্টি পেমেন্ট এপিআই ডাউন থাকার কারণে আমার CI পাইপলাইন ফেইল করেছিল, তখন আমি খুব কঠিনভাবে একটা লেসন শিখেছিলাম। যে টেস্টগুলো রিয়েল নেটওয়ার্কে হিট করে, সেগুলো আসলে কোনো টেস্ট নয়, এগুলো অনেকটা আবহাওয়ার পূর্বাভাসের মতো।
আপনি যদি সঠিক নিয়মে HTTP Requests in PHP মক (mock) করতে চান, তবে আপনার লক্ষ্য হওয়া উচিত এমন একটা টেস্ট স্যুট তৈরি করা, যা দুপুর বেলা বিল্ড সার্ভারে ঠিক যে রেজাল্ট দেবে, রাত ৩টায় ফ্লাইটে বসে অফলাইনে টেস্ট করলেও ঠিক একই রেজাল্ট দেবে।

এই গাইডে আমরা PHP তে HTTP রিকোয়েস্ট মক করার সেরা পদ্ধতিগুলো নিয়ে আলোচনা করব।
What is an HTTP Request?
HTTP (Hypertext Transfer Protocol) রিকোয়েস্ট হলো ক্লায়েন্ট (যেমন- আপনার ব্রাউজার বা PHP অ্যাপ্লিকেশন) এবং সার্ভারের মধ্যে যোগাযোগের মাধ্যম।
সহজ কথায়, যখন আপনার অ্যাপ্লিকেশন অন্য কোনো সার্ভার থেকে ডেটা চায় বা পাঠাতে চায় (যেমন- পেমেন্ট গেটওয়ে, ওয়েদার এপিআই), তখন সে একটি HTTP রিকোয়েস্ট পাঠায়।
Why are HTTP Requests Needed in PHP?
মডার্ন ওয়েব ডেভেলপমেন্টে একটি অ্যাপ্লিকেশন কখনোই একা চলতে পারে না। PHP তে HTTP রিকোয়েস্ট মূলত নিচের কাজগুলোর জন্য প্রয়োজন হয়:
- Third-Party API Integration: পেমেন্ট গেটওয়ে (Stripe, PayPal), এসএমএস সার্ভিস (Twilio) বা সোশ্যাল মিডিয়া লগইন এর জন্য।
- Microservices Communication: আলাদা আলাদা সার্ভিস বা অ্যাপ্লিকেশনের মধ্যে ডেটা আদান-প্রদান করতে।
- Data Fetching: অন্য সার্ভার থেকে রিয়েল-টাইম ডেটা (যেমন- ওয়েদার আপডেট, স্টক মার্কেট ডেটা) নিয়ে আসতে।
- Webhooks: অন্য সিস্টেম থেকে আসা ইভেন্ট নোটিফিকেশন রিসিভ করতে।
Why You Should Mock HTTP in Tests at All
টেস্টে লাইভ এন্ডপয়েন্টে হিট করলে আপনার টেস্ট স্যুট এমন সব বিষয়ের ওপর নির্ভরশীল হয়ে পড়ে, যার কোনো কন্ট্রোল আপনার হাতে নেই। রিয়েল API কল করা বন্ধ করার পেছনে মূল কারণগুলো হলো:
- Deterministic: মক করা রেসপন্স সবসময় একই ডেটা রিটার্ন করে। তাই টেস্ট ফেইল করলে বুঝতে পারবেন সমস্যা আপনার কোডেই।
- Fast Execution: DNS লুকআপ বা স্লো নেটওয়ার্কের জন্য অপেক্ষা করতে হয় না। মক কল কয়েক মাইক্রোসেকেন্ডেই কমপ্লিট হয়।
- Offline Testing: ইন্টারনেট ছাড়াই যেকোনো পরিবেশে (যেমন- ট্রেনে বা CI রানারে) টেস্ট করা যায়।
- No Rate Limits: API কোটা শেষ হওয়ার ভয় ছাড়াই হাজার বার টেস্ট রান করা সম্ভব।
- Simulate Failures: 500 Server Error, টাইমআউট বা ভুল ডেটার মতো এজ-কেসগুলো সহজেই সিমুলেট করা যায়, যা প্রোডাকশনে ব্রেক করার অন্যতম কারণ।
The Guzzle-Native Approach: MockHandler
আপনি যদি সরাসরি Guzzle ব্যবহার করেন, তবে এর বিল্ট-ইন MockHandler হলো পারফেক্ট টুল। এটি দিয়ে আপনি আগে থেকেই ফেক রেসপন্স কিউ (queue) করে রাখতে পারেন।
PHP
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
$mock = new MockHandler([
new Response(200, [], '{"status": "active"}'),
new Response(500, [], 'Server Error')
]);
$client = new Client(['handler' => HandlerStack::create($mock)]);
$response = $client->get('/status'); // Returns 200
- কিভাবে কাজ করে: এটি FIFO (First-In-First-Out) পদ্ধতিতে কাজ করে। প্রথম রিকোয়েস্ট প্রথম রেসপন্স পাবে।
- অ্যাডভান্টেজ: এক্সেপশন (যেমন-
RequestException) থ্রো করে রিট্রাই লজিকও টেস্ট করা যায়।
Asserting Requests with History Middleware
কোড সঠিক রিকোয়েস্ট (URL, Header, Body) পাঠিয়েছে কি না, তা চেক করতে Guzzle-এর History মিডলওয়্যার ব্যবহার করুন।
PHP
use GuzzleHttp\Middleware;
$container = [];
$history = Middleware::history($container);
$stack->push($history); // Add to HandlerStack
// After making a request:
$this->assertCount(1, $container);
$this->assertSame('POST', $container[0]['request']->getMethod());
The Laravel Approach: Http::fake()
লারাভেলে HTTP মক করা অনেক সহজ। Http::fake() দিয়ে URL অনুযায়ী প্যাটার্ন ম্যাচ করানো যায়।
PHP
use Illuminate\Support\Facades\Http;
Http::fake([
'github.com/*' => Http::response(['plan' => 'pro'], 200),
'*' => Http::response([], 200), // Catch-all rule (Must be at the bottom)
]);
Pro Tip: লারাভেলে Http::assertSent() এবং Http::assertNotSent() ব্যবহার করে রিকোয়েস্ট ইন্সপেক্ট করা যায়।
Catching Stray Requests (Must Do)
যেকোনো রিয়েল HTTP Requests in PHP ভুলে নেটওয়ার্কে চলে যাওয়া ঠেকাতে এই সেফটি নেটটি ব্যবহার করুন:
PHP
Http::preventStrayRequests();
এটি আপনার বেস টেস্ট কেসে বসিয়ে দিলে, ফেক করা হয়নি এমন যেকোনো রিকোয়েস্ট নীরবে রিয়েল সার্ভারে হিট করার বদলে এক্সেপশন থ্রো করবে।
The Ultimate Rule: Don’t Mock What You Don’t Own
থার্ড-পার্টি লাইব্রেরিকে (যেমন- Guzzle) সরাসরি টেস্টে মক করা টেকনিক্যাল ডেট বাড়ায়। এর বদলে একটি ইন্টারফেস তৈরি করুন:
PHP
interface WeatherGateway {
public function getTemperature(string $city): float;
}
এরপর আপনার টেস্টে Guzzle-এর বদলে এই WeatherGateway ইন্টারফেসটিকে মক করুন। এতে ভবিষ্যতে HTTP ক্লায়েন্ট পরিবর্তন করলেও টেস্ট ব্রেক করবে না।
Common Pitfalls to Avoid
- Forgetting
preventStrayRequests(): এটি ছাড়া ভুল মক প্যাটার্ন নীরবে রিয়েল API-তে হিট করবে। - Not Asserting the Request: শুধু রেসপন্স হ্যান্ডেল করাই যথেষ্ট নয়, সঠিক পেলোড পাঠানো হয়েছে কি না তাও চেক করুন।
- Hardcoding Large Responses: বড় JSON রেসপন্স ইনলাইনে না লিখে ফিক্সচার (fixtures) ফাইল থেকে লোড করুন।
- Ignoring Failure Paths: টাইমআউট এবং 500 এরর অবশ্যই মক করে টেস্ট করুন।
Wrapping Up
সিস্টেমে HTTP রিকোয়েস্ট মক করা মানে শুধু ফেক ডেটা রিটার্ন করা নয়, বরং একটি ক্লিন বাউন্ডারি তৈরি করা।
Guzzle-এর ক্ষেত্রে MockHandler এবং লারাভেলের ক্ষেত্রে Http::fake() ব্যবহার করুন। আর অবশ্যই আজই আপনার প্রজেক্টে preventStrayRequests() গার্ড যুক্ত করে নিন!




