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

如何用RSpec验证POST请求的请求体?

解决方案

方法一:Mock Net::HTTP#request 捕获请求对象做断言

通过Mock Net::HTTP 实例的 request 方法,捕获传入的请求对象,直接验证其请求体和Content-Type是否符合预期:

it "carries the expected request body with correct content type" do
  test_data = { id: 123 }
  expected_body = test_data.to_json

  # Mock Net::HTTP.new 返回一个带request方法的模拟实例
  http_mock = double("Net::HTTP")
  expect(Net::HTTP).to receive(:new).with("example.com", 443).and_return(http_mock)

  # 捕获request方法接收的请求对象,执行断言
  expect(http_mock).to receive(:request) do |request|
    expect(request.content_type).to eq("application/json")
    expect(request.body).to eq(expected_body)
    # 返回模拟响应,避免方法因无返回值报错
    double("response", code: "200", body: { success: true }.to_json)
  end

  Gateway.new.post_it(test_data)
end

方法二:用WebMock拦截并验证请求

WebMock可以直接拦截HTTP请求,无需手动Mock底层类,就能验证请求的URI、请求体、headers等所有细节:

  1. 先在Gemfile的test组添加WebMock:
group :test do
  gem 'webmock'
end
  1. 编写测试代码:
require 'webmock/rspec'

it "sends request to correct URI with expected body" do
  test_data = { id: 123 }
  expected_body = test_data.to_json

  # 拦截目标请求,设置验证规则和模拟响应
  stub_request(:post, "https://example.com/api")
    .with(
      body: expected_body,
      headers: { 'Content-Type' => 'application/json' }
    )
    .to_return(status: 200, body: { success: true }.to_json)

  Gateway.new.post_it(test_data)

  # 验证请求确实按规则被触发
  expect(WebMock).to have_requested(:post, "https://example.com/api")
    .with(body: expected_body, headers: { 'Content-Type' => 'application/json' })
end

这种方式比手动Mock更简洁,同时能覆盖完整的请求校验场景,无需依赖真实API服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:12:06