如何在不调用外部API的情况下,为应用内update_candidate_assessment接口编写返回模拟响应的测试用例
Got it, let's tackle this: you need to test your update_candidate_assessment endpoint without actually triggering the external API it relies on. The key here is to mock or stub the external API response so your test only focuses on your code's behavior, not the third-party service.
Two Reliable Approaches
1. Use WebMock to Intercept HTTP Requests
If your endpoint calls the external API via HTTP (like with Faraday, Net::HTTP, or any HTTP client), WebMock is perfect for blocking those requests and returning fake responses.
First, make sure WebMock is set up in your test environment:
# Add this to your Gemfile's test group group :test do gem 'webmock' end
Then update your test case to stub the external API before hitting your endpoint:
require 'webmock/rspec' describe "PUT /v1/workday/update_candidate_assessment", type: :request do it "returns a success response without calling the external API" do # Replace this with the actual URL of the external API your endpoint calls external_api_url = "https://your-external-api.com/candidate-assessments" # Stub the external API request to return a fake successful response stub_request(:post, external_api_url) .to_return( status: 200, body: { success: true }.to_json, headers: { 'Content-Type' => 'application/json' } ) # Send the request to your local endpoint put "/api/v1/workday/update_candidate_assessment", params: { api_key: "dsfds", data: { client_id: "r53535", campaign_id: "R5343", assessed_on_date: "2021-06-10", candidate_id: "6353636", assessment_test_reference: "View1", assessment_status_reference: "Status", assessment_score: "10", assessment_status_id: "rsgshs" } } # Parse the response once to clean up your assertions parsed_response = JSON.parse(response.body) # Run your assertions as before expect(response).to have_http_status(:success) expect(parsed_response.size).to eq(3) expect(parsed_response).to have_keys("body", "description", "message") expect(parsed_response["message"]).to include("Success") end end
2. Stub a Wrapper Service Class
If you've wrapped the external API call in a dedicated service class (like WorkdayAssessmentService), you can directly stub that class's method instead of dealing with HTTP requests. This is cleaner if you have a well-structured codebase.
Here's how that looks:
describe "PUT /v1/workday/update_candidate_assessment", type: :request do it "returns a success response without calling the external API" do # Stub the service method to return a fake successful result # Adjust the method name and arguments to match your actual service allow(WorkdayAssessmentService).to receive(:update_assessment) .with(any_args) .and_return({ success: true }) # Send the request to your local endpoint put "/api/v1/workday/update_candidate_assessment", params: { api_key: "dsfds", data: { client_id: "r53535", campaign_id: "R5343", assessed_on_date: "2021-06-10", candidate_id: "6353636", assessment_test_reference: "View1", assessment_status_reference: "Status", assessment_score: "10", assessment_status_id: "rsgshs" } } # Parse the response once for cleaner assertions parsed_response = JSON.parse(response.body) # Run your assertions expect(response).to have_http_status(:success) expect(parsed_response.size).to eq(3) expect(parsed_response).to have_keys("body", "description", "message") expect(parsed_response["message"]).to include("Success") end end
Quick Tips
- Test error scenarios too: You can stub the external API to return 400/500 status codes to make sure your endpoint handles errors correctly.
- Avoid repeated JSON parsing: Extracting
parsed_responseonce makes your test code easier to read and maintain. - WebMock defaults: WebMock blocks all external HTTP requests by default in test mode, so you don't have to worry about accidental real calls slipping through.
内容的提问来源于stack exchange,提问作者Chetan Barawkar

