Я знаю, что название немного расплывчато, но я не знаю, что там надеть.
Я разрабатываю API с Sinatra для нашего бэкенда в Ruby. Дело в том, что мне нужно иметь возможность передавать JSON службе, представляющей пользователя. Проблема, с которой я сталкиваюсь, состоит в том, что когда я запускаю свои тесты, это не работает, но делает это вручную против службы, это работает. Я предполагаю, что есть проблема с форматом JSON.
Я обновил свою модель User, чтобы полагаться на помощников из ActiveModel для сериализации JSON. У меня было слишком много проблем с ручными преобразованиями. Вот как выглядит базовая модель пользователя:
class User
include ActiveModel::Serializers::JSON
attr_accessor :login, :email, :birthday, :created_at, :updated_at, :password_sha, :password_salt
# Creates a new instance of the class using the information stored
# in the hash. If data is missing then nill will be assigned to the
# corresponding property.
def initialize(params = {})
return if params.nil?
self.login = params[:login] if params.key?("login")
self.email = params[:email] if params.key?("email")
self.birthday = Time.parse(params[:birthday]) rescue Time.now
if params.key?("password_salt") && params.key?("password_sha")
self.password_salt = params["password_salt"]
self.password_sha = params["password_sha"]
elsif params.key?("password")
self.set_password(params[:password])
end
self.created_at = Time.now
end
def attributes
{:login => self.login, :email => self.email, :birthday => self.birthday, :created_at => self.created_at, :updated_at => self.updated_at, :password_sha => self.password_sha, :password_salt => self.password_salt}
end
def attributes=(params = {})
self.login = params['login']
self.email = params['email']
self.birthday = params['birthday']
self.created_at = params['created_at']
self.updated_at = params['updated_at']
self.password_sha = params['password_sha']
self.password_salt = params['password_salt']
end
end
Я использую Cucumber, Rack :: Test и Capybara для тестирования моей реализации API.
Код приложения API выглядит следующим образом:
# This action will respond to POST request on the /users URI,
# and is responsible for creating a User in the various systems.
post '/users' do
begin
user = User.new.from_json(request.body.read)
201
rescue
400
end
end
В приведенном выше фрагменте я ожидаю представление json в теле запроса. По какой-то причине хэш params здесь пуст, не знаю почему
Тестовая секция, которая делает актуальную стойку, выглядит так:
When /^I send a POST request to "([^\"]*)" with the following:$/ do |path, body|
post path, User.new(body.hashes.first).to_json, "CONTENT_TYPE" => "application/json"
end
Пример выходной строки JSON, сгенерированной файлом User.rb, выглядит следующим образом:
"{"user":{"birthday":"1985-02-14T00:00:00+01:00","created_at":"2012-03-23T12:54:11+01:00","email":"arne.de.herdt@gmail.com","login":"airslash","password_salt":"x9fOmBOt","password_sha":"2d3afc55aee8d97cc63b3d4c985040d35147a4a1d312e6450ebee05edcb8e037","updated_at":null}}"
Вывод копируется из Rubymine IDE, но когда я отправляю это в приложение, я не могу его проанализировать, потому что:
- Хэш params пуст при использовании тестов
- выполнение этого вручную дает мне ошибку о необходимости как минимум 2 октета.