Tengo el siguiente código en mi controlador:

format.json { render :json => { 
        :flashcard  => @flashcard,
        :lesson     => @lesson,
        :success    => true
} 

En mi RSpec de prueba del controlador quiero verificar que un determinado escenario de no recibir un éxito la respuesta json por lo que tengo la siguiente línea:

controller.should_receive(:render).with(hash_including(:success => true))

Aunque cuando ejecuto mis pruebas me sale el siguiente error:

Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
 (#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
     expected: 1 time
     received: 0 times

Estoy comprobar la respuesta incorrecta?

InformationsquelleAutor Fizz | 2011-03-01

9 Comentarios

  1. 162

    Puede examinar el objeto de respuesta y comprobar que contiene el valor esperado:

    @expected = { 
            :flashcard  => @flashcard,
            :lesson     => @lesson,
            :success    => true
    }.to_json
    get :action # replace with action name /params as necessary
    response.body.should == @expected

    EDITAR

    Cambiar esto a un post hace un poco más complicado. He aquí una manera de manejarlo:

     it "responds with JSON" do
        my_model = stub_model(MyModel,:save=>true)
        MyModel.stub(:new).with({'these' => 'params'}) { my_model }
        post :create, :my_model => {'these' => 'params'}, :format => :json
        response.body.should == my_model.to_json
      end

    Nota que mock_model no responden a la to_json, por lo que sea stub_model o un verdadero modelo de instancia que se necesita.

    • He intentado esto y, lamentablemente, se dice que tuvo una respuesta de » «. Este podría ser un error en el controlador?
    • También la acción es ‘crear’, qué importa que yo uso un post en lugar de get?
    • Sí, usted quiere post :create con parámetros válidos hash.
    • Usted también debe especificar el formato que usted está solicitando. post :create, :format => :json
    • Buen punto, voy a editar para reflejar que
    • Genial, esto funcionó una vez que he añadido :formato => :json. Gracias.
    • JSON es sólo una cadena, una secuencia de caracteres y el orden de los asuntos. {"a":"1","b":"2"} y {"b":"2","a":"1"} no son iguales las cadenas que anotar la igualdad de los objetos. Usted no debe comparar cadenas, sino que los objetos, hacer JSON.parse('{"a":"1","b":"2"}').should == {"a" => "1", "b" => "2"} lugar.

  2. 156

    Se podría analizar el cuerpo de la respuesta como esta:

    parsed_body = JSON.parse(response.body)

    A continuación, usted puede hacer sus afirmaciones en contra de que se analiza el contenido.

    parsed_body["foo"].should == "bar"
    • esto parece mucho más fácil. Gracias.
    • En primer lugar, muchas gracias. Una pequeña corrección: JSON.parse(respuesta.cuerpo) devuelve una matriz. [‘foo’] sin embargo, busca una clave en un valor de hash. Corregido uno es parsed_body[0][‘foo’].
    • JSON.analizar sólo devuelve un array si hubo una matriz en la cadena JSON.
    • JSON.parse(respuesta.cuerpo) está regresando completo en HTML de la página.
    • si es que regresan HTML, a continuación, su respuesta no es json. Asegúrese de que su solicitud es la especificación del formato json.
    • Usted podría también utilizar b = JSON.parse(response.body, symoblize_names: true) de modo que usted puede acceder a ellos a través de símbolos como: b[:foo]
    • El uso de la «respuesta».parsed_body». No hay necesidad de JSON.analizar si «le foo_url, como: :json».

  3. 45

    Edificio de Kevin Trowbridge la respuesta

    response.header['Content-Type'].should include 'application/json'
    • rspec-rails ofrece un comparador para esto: esperar respuesta.content_type).eq(«application/json»)
    • No podía usted sólo tiene que utilizar Mime::JSON en lugar de 'application/json'?
    • Creo que se necesita Mime::JSON.to_s
  4. 12

    Simple y fácil manera de hacer esto.

    # set some variable on success like :success => true in your controller
    controller.rb
    render :json => {:success => true, :data => data} # on success
    
    spec_controller.rb
    parse_json = JSON(response.body)
    parse_json["success"].should == true
    • JSON(str) funciona para mí. Gracias
  5. 10

    También puede definir una función auxiliar en el interior de spec/support/

    module ApiHelpers
      def json_body
        JSON.parse(response.body)
      end
    end
    
    RSpec.configure do |config| 
      config.include ApiHelpers, type: :request
    end

    y uso json_body siempre que usted necesite para tener acceso a la respuesta en JSON.

    Por ejemplo, en el interior de su solicitud de especificación que puede utilizar directamente

    context 'when the request contains an authentication header' do
      it 'should return the user info' do
        user  = create(:user)
        get URL, headers: authenticated_header(user)
    
        expect(response).to have_http_status(:ok)
        expect(response.content_type).to eq('application/vnd.api+json')
        expect(json_body["data"]["attributes"]["email"]).to eq(user.email)
        expect(json_body["data"]["attributes"]["name"]).to eq(user.name)
      end
    end
  6. 7

    Otro enfoque de la prueba sólo para una respuesta JSON (no es que el contenido dentro contiene un valor esperado), es analizar la respuesta mediante ActiveSupport:

    ActiveSupport::JSON.decode(response.body).should_not be_nil

    Si la respuesta es no parsable JSON se producirá una excepción y la prueba fallará.

  7. 7

    Usted podría mirar en el 'Content-Type' encabezado para ver de que es el correcto?

    response.header['Content-Type'].should include 'text/javascript'
    • Para render :json => object, creo que Rails devuelve un encabezado de Tipo de Contenido de ‘application/json’.
    • La mejor opción creo: response.header['Content-Type'].should match /json/
    • Gusta porque mantiene las cosas simples y no agregar una nueva dependencia.
  8. 5

    Cuando se utiliza Rails 5 (actualmente en beta), hay un nuevo método, parsed_body en la prueba de respuesta, que devolverá la respuesta se analiza como lo de la última solicitud fue codificado en.

    El commit en GitHub: https://github.com/rails/rails/commit/eee3534b

    • Rieles de 5 de salir de la beta, junto con #parsed_body. Todavía no está documentado, pero al menos en formato JSON obras. Tenga en cuenta que las claves son todavía las cadenas (en lugar de los símbolos), de manera que uno puede encontrar #deep_symbolize_keys o #with_indifferent_access útil (a mi me gusta el último).

Dejar respuesta

Please enter your comment!
Please enter your name here