Я очень !! new ruby и Rspe c пользователь изо всех сил пытается понять, как выполнить модульное тестирование того, что запрос API установил ожидаемую полезную нагрузку запроса, при этом имитируя ответ от внешнего API. Я реализовал запросы API, используя Net: HTTP, чтобы ограничить зависимости.
Метод тестируемый
def lint (url, path, headers={ "Content-Type" => "application/json" }, timeout=10)
if yamlContent = GitLab::Lint::Client::YamlFile.new(path).get_json_content()
uri = URI.parse(url)
req = Net::HTTP::Post.new(uri, headers)
req.body = { content: yamlContent }.to_json
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = https.request(req)
case response
when Net::HTTPSuccess
puts "Linting request successful"
return JSON.parse(response.body)
when Net::HTTPUnauthorized
abort("#{response.message}: invalid token in api request?")
when Net::HTTPServerError
abort('error' => "#{response.message}: server error, try again later?")
when Net::HTTPBadRequest
puts "Bad request..." + req.body
abort("#{response.message}: bad api request?")
when Net::HTTPNotFound
abort("#{response.message}: api request not found?")
else
puts "Failed validation\nJSON payload :: #{req.body}\nHTTP Response: #{response.message}"
abort("#{response.message}: failed api request?")
end
else
abort("\nLint request failed, problem encountered reading yaml file")
end
end
RSpe c test
require "gitlab/lint/client/api"
RSpec.describe Gitlab::Lint::Client::Api do
describe "#initialize" do
it "initialises" do
api = Gitlab::Lint::Client::Api.new
expect(api).to be_instance_of(Gitlab::Lint::Client::Api)
end
end
describe "#lint" do
before(:each) do
@response = instance_double(Net::HTTPSuccess, body: @response_body, message: 'OK')
@response_body = { 'status' => 'valid', 'errors' => [] }.to_json
@request_mock = instance_double(Net::HTTP::Post)
allow(@request_mock).to receive(:[]=)
allow(@request_mock).to receive(:body=)
allow(Net::HTTP::Post).to receive(:new).and_return(@request_mock)
@http_client_mock = instance_double(Net::HTTP)
allow(@http_client_mock).to receive(:use_ssl=)
allow(@http_client_mock).to receive(:verify_mode=)
allow(@http_client_mock).to receive(:request)
allow(Net::HTTP).to receive(:new).and_return(@http_client_mock)
allow(@http_client_mock).to receive(:request).with(@request_mock).and_return(@response)
@endpoint_url = 'http://gitlab.com'
@fileName='test.yml'
allow(File).to receive(:exist?).with(@fileName).and_return(true)
allow(File).to receive(:readable?).with(@fileName).and_return(true)
allow(YAML).to receive(:load_file).with(@fileName).and_return("image: ruby:latest")
end
it "lints successfully" do
# for a valid case we want:
# - test that the request body was set with content as expected
# - simulate the response to be { status: "valid", "errors": []}
api = Gitlab::Lint::Client::Api.new
api.lint(@endpoint_url, @fileName)
expect(@request_mock.body).to have_received({ content: {'image' => 'ruby:latest'} }.to_json)
end
end
end
Запуск теста дает следующий ошибочный вывод:
Gitlab::Lint::Client::Api
#initialize
initialises
#lint
OK: failed api request? # this output signifies that the case structure has not recognised the response as a HTTPSuccess instance
Ответ не рассматривается как экземпляр Net :: HTTPSuccess в структура корпуса моего тестируемого метода lint . Как смоделировать экземпляр Net :: HTTPSuccess ?