Я поставлен в тупик с проблемой тестирования API-интерфейса rails, надеюсь, что кто-то может помочь.
Я создаю серверную часть API-интерфейса rails и создал каркас для "Сотрудники" с четырьмя полями,а именно: имя, фамилия, телефон, электронная почта. Проблема, с которой я столкнулся, заключается в том, что мой тест «Создать» не выполняется, со следующей ошибкой:
Minitest::UnexpectedError: ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"api/v1/employees"}, missing required keys: [:id]
Однако я не могу понять, почему (я гуглили переполнение стека поиска, и никто не может найти решение этой проблемы).
Сервер разработчика
Используя Httpie, я протестировал метод post в dev, и он, кажется, работает правильно, см. Ниже:
Когда я запускаю http POST localhost:3000/api/v1/employees first_name=Edward last_name=Peters phone=0231231231 email=123@test.com
Я получаю следующий ответ:
HTTP/1.1 201 Created
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"55f26b9df2c29403bab760101fe31475"
Referrer-Policy: strict-origin-when-cross-origin
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: 8d9e2dd1-7fdc-4379-be2b-3b060270bac2
X-Runtime: 0.059854
X-XSS-Protection: 1; mode=block
{
"created_at": "2019-10-30T21:42:43.083Z",
"email": "123@test.com",
"first_name": "Edward",
"id": 52,
"last_name": "Peters",
"phone": "0231231231",
"updated_at": "2019-10-30T21:42:43.083Z"
}
Исходя из этого, похоже, что действие контроллера работает правильно, однако тест не пройден. Мой контроллер и тест выглядят следующим образом:
api / v1 / employee_controller.rb
module Api
module V1
class EmployeesController < ApplicationController
before_action :set_employee, only: [:show, :update, :destroy]
# GET /employees
def index
@employees = Employee.all
render json: @employees
end
# GET /employees/1
def show
render json: @employee
end
**# POST /employees
def create
@employee = Employee.new(employee_params)
if @employee.save
render json: @employee, status: :created
else
render json: @employee.errors, status: :unprocessable_entity
end
end**
# PATCH/PUT /employees/1
def update
if @employee.update(employee_params)
render json: @employee
else
render json: @employee.errors, status: :unprocessable_entity
end
end
# DELETE /employees/1
def destroy
@employee.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_employee
@employee = Employee.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def employee_params
params.require(:employee).permit(:first_name, :last_name, :phone, :email)
end
end
end
end
employee_controller_test.rb
require 'test_helper'
class EmployeesControllerTest < ActionDispatch::IntegrationTest
setup do
@employee = employees(:one)
@update_employee = employees(:two)
end
test "should get index" do
get api_v1_employees_url, as: :json
assert_response :success
end
test "should create employee" do
assert_difference('Employee.count' ) do
print "Employee id: #{Employee.last.id}"
post api_v1_employee_url, params: { employee: {
email: @employee.email,
first_name: @employee.first_name,
last_name: @employee.last_name,
phone: @employee.phone }
}, as: :json
print "Employee id: #{Employee.last.id}"
end
follow_redirect!
assert_response 201
end
test "should show employee" do
get api_v1_employee_url(@employee), as: :json
assert_response :success
end
test "should update employee" do
patch api_v1_employee_url(@employee), params: { employee: {
email: @update_employee.email,
first_name: @update_employee.first_name,
last_name: @update_employee.last_name,
phone: @update_employee.phone }
}, as: :json
assert_response 200
end
test "should destroy employee" do
assert_difference('Employee.count', -1) do
delete api_v1_employee_url(@employee), as: :json
end
assert_response 204
end
end
Работая с ошибкой, о которой я упоминал выше, похоже, что тест не выполняется, когда метод пытается вернуть ответ json для новой записи. Однако, глядя на сам метод, кажется, что он должен получить это при сохранении переменной @employee
.
Большое спасибо за любые советы!