Eu tenho o seguinte código no meu controlador:
format.json { render :json => {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}
No meu teste do controlador RSpec, quero verificar se um determinado cenário recebe uma resposta json bem-sucedida, portanto, tive a seguinte linha:
controller.should_receive(:render).with(hash_including(:success => true))
Embora ao executar meus testes, recebo o seguinte erro:
Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
(#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
expected: 1 time
received: 0 times
Estou verificando a resposta incorretamente?
ruby-on-rails
json
rspec
Efervescer
fonte
fonte
post :create
com um hash de parâmetros válido.post :create, :format => :json
{"a":"1","b":"2"}
e{"b":"2","a":"1"}
não são cadeias iguais que notam objetos iguais. Você não deve comparar seqüências de caracteres, mas objetosJSON.parse('{"a":"1","b":"2"}').should == {"a" => "1", "b" => "2"}
.Você pode analisar o corpo da resposta assim:
Então você pode fazer suas afirmações contra esse conteúdo analisado.
fonte
b = JSON.parse(response.body, symoblize_names: true)
para poder acessá-los usando símbolos da seguinte maneira:b[:foo]
Partindo da resposta de Kevin Trowbridge
fonte
Mime::JSON
vez de'application/json'
?Mime::JSON.to_s
Há também a json_spec gem, que vale a pena dar uma olhada
https://github.com/collectiveidea/json_spec
fonte
Simples e fácil de fazer isso.
fonte
Você também pode definir uma função auxiliar dentro
spec/support/
e use
json_body
sempre que precisar acessar a resposta JSON.Por exemplo, dentro das especificações de sua solicitação, você pode usá-lo diretamente
fonte
Outra abordagem para testar apenas uma resposta JSON (não que o conteúdo contenha um valor esperado) é analisar a resposta usando o ActiveSupport:
Se a resposta não for analisável JSON, uma exceção será lançada e o teste falhará.
fonte
Você pode olhar no
'Content-Type'
cabeçalho para ver se está correto?fonte
render :json => object
, acredito que o Rails retorna um cabeçalho Content-Type de 'application / json'.response.header['Content-Type'].should match /json/
Ao usar o Rails 5 (atualmente ainda em beta), há um novo método,
parsed_body
na resposta do teste, que retornará a resposta analisada como a última solicitação codificada.O commit no GitHub: https://github.com/rails/rails/commit/eee3534b
fonte
#parsed_body
. Ainda não está documentado, mas pelo menos o formato JSON funciona. Observe que as teclas ainda são strings (em vez de símbolos); portanto, pode-se achar útil#deep_symbolize_keys
ou#with_indifferent_access
útil (eu gosto do último).Se você quiser tirar proveito das diferenças de hash fornecidas pelo Rspec, é melhor analisar o corpo e comparar com um hash. Maneira mais simples que eu encontrei:
fonte
Solução de comparação JSON
Rende um Diff limpo, mas potencialmente grande:
Exemplo de saída do console a partir de dados reais:
(Obrigado a comentar por @floatingrock)
Solução de comparação de cadeias
Se você deseja uma solução revestida de ferro, evite usar analisadores que possam introduzir igualdade de falsos positivos; compare o corpo da resposta com uma sequência. por exemplo:
Mas essa segunda solução é menos visualmente amigável, pois usa JSON serializado, o que incluiria muitas aspas vazias.
Solução de correspondência personalizada
Costumo escrever para mim mesmo um correspondente personalizado que faz um trabalho muito melhor de identificar exatamente em qual slot recursivo os caminhos JSON diferem. Adicione o seguinte às suas macros rspec:
Exemplo de uso 1:
Exemplo de uso 2:
Exemplo de saída:
Outro exemplo de saída para demonstrar uma incompatibilidade profunda em uma matriz aninhada:
Como você pode ver, a saída informa EXATAMENTE onde corrigir o JSON esperado.
fonte
Encontrei um correspondência de cliente aqui: https://raw.github.com/gist/917903/92d7101f643e07896659f84609c117c4c279dfad/have_content_type.rb
Coloque-o em spec / support / matchers / have_content_type.rb e certifique-se de carregar coisas do suporte com algo parecido com isto em spec / spec_helper.rb
Aqui está o código em si, para o caso de ele desaparecer do link fornecido.
fonte
Muitas das respostas acima estão um pouco desatualizadas, portanto, este é um resumo rápido de uma versão mais recente do RSpec (3.8+). Esta solução não gera avisos do rubocop-rspec e está alinhada com as práticas recomendadas do rspec :
Uma resposta JSON bem-sucedida é identificada por duas coisas:
application/json
Supondo que o objeto de resposta seja o assunto anônimo do teste, ambas as condições acima podem ser validadas usando os correspondentes incorporados do Rspec:
Se você estiver preparado para nomear seu assunto, os testes acima podem ser mais simplificados:
fonte