如何用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等所有细节:
- 先在Gemfile的test组添加WebMock:
group :test do gem 'webmock' end
- 编写测试代码:
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
相关产品推荐
相关产品推荐

