You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails项目中请求体变化时如何Stub Mailjet API请求?

Fixing Dynamic Request Body Issues When Stubbing Mailjet API in RSpec

Hey there! I’ve dealt with this exact frustration before—when you generate a stub with WebMock but can’t reuse it because parts of the request body (like that reset password token) change every time. Let’s break down how to make your stubs flexible enough to handle dynamic content while still verifying the important parts.

Option 1: Use WebMock’s Hash Matchers for Flexible Body Matching

Instead of hardcoding the entire JSON string, let WebMock parse the request body into a hash and match against the fixed, critical fields. This ignores any dynamic values you don’t care about.

Here’s how to adjust your stub:

stub_request(:post, "https://api.mailjet.com/v3/send")
  .with(
    body: hash_including(
      "FromEmail" => "abc@abc.com",
      "FromName" => "abc",
      "To" => "abc@abc.com",
      "Subject" => "Forgot Password"
    )
  )

If you want to add a little more rigor (like ensuring the dynamic part follows a pattern), you can use a regex for specific fields:

stub_request(:post, "https://api.mailjet.com/v3/send")
  .with(
    body: hash_including(
      "FromEmail" => "abc@abc.com",
      "FromName" => "abc",
      "To" => "abc@abc.com",
      "Subject" => "Forgot Password",
      "Text-part" => /^xV3SEtaoa1oyYYfY/ # Matches the fixed prefix of your token
    )
  )

Option 2: Stub the Mailjet Client Directly (Instead of HTTP Requests)

If you’re using the official mailjet-ruby gem, it’s often cleaner to stub the client method rather than the raw HTTP call. This lets you work at a higher level and avoid dealing with request body formatting entirely.

Example:

# In your spec
allow(Mailjet::Message).to receive(:send) do |message_params|
  # Assert that the parameters are correct
  expect(message_params[:FromEmail]).to eq("abc@abc.com")
  expect(message_params[:Subject]).to eq("Forgot Password")
  
  # Return a mock successful response
  { "Messages" => [{ "Status" => "success" }] }
end

Bonus: Verify the Request Was Actually Made

To ensure your code is hitting the stub (and not the real API), you can add an assertion with WebMock’s have_requested:

expect(a_request(:post, "https://api.mailjet.com/v3/send")
  .with(body: hash_including("Subject" => "Forgot Password"))).to have_been_made.once

These approaches keep your stubs maintainable, even when dynamic parts of the request body change. No more copying and pasting updated JSON strings every time!

内容的提问来源于stack exchange,提问作者awsm sid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:46:12