0

I am trying to create a mock object and i am checking whether my method receives the right param and expected result.

Below is my spec.

require 'spec_helper'

describe User do 

  let(:username) {"test@test.com"}
  let(:password) {"123"}
  let(:code) {"0"}

  context "when signing in" do 

    it "should sign in" do 
      user = double("user")
      expected_results = {
        "token": "123"
      }
      allow(user).to receive(:login).with({email: username, password: password, code: code})
        .and_return(expected_results)
      expect(user.login).to eq(expected_results)
    end

  end    
end

Is there a way to separate my json from it block and keep it outside?.

UnderTaker
  • 853
  • 3
  • 13
  • 22
  • Does this help?: http://stackoverflow.com/questions/5159882/how-to-check-for-a-json-response-using-rspec/5161898 – zetetic Aug 12 '14 at 20:33
  • @zetetic: I looked that, but it not help... – UnderTaker Aug 12 '14 at 20:36
  • I'm not clear on the question. Do you want just want to set the value of `expected_results` outside the example? You can do that by adding a `let` in the inner context. – zetetic Aug 12 '14 at 20:38
  • @zetetic: Can you show that example, coz its failing. Also am i doing the right way of testing? – UnderTaker Aug 12 '14 at 20:46

2 Answers2

0

You can use a before do block in the context or before the context.

Here is the reference: https://www.relishapp.com/rspec/rspec-core/docs/hooks/before-and-after-hooks

Rafal
  • 2,576
  • 2
  • 18
  • 13
0

You can use let inside a context block to set the value of a variable for the examples nested within:

require 'spec_helper'

describe User do 

  let(:username) {"test@test.com"}
  let(:password) {"123"}
  let(:code) {"0"}

  context "when signing in" do
    let(:expected_results) { {token:"123"}.to_json }

    it "should sign in" do 
      user = double("user")
      allow(user).to receive(:login).with({email: username, password: password, code: code})
        .and_return(expected_results)
      expect(user.login).to eq(expected_results)
    end

  end    
end

am i doing the right way of testing?

Not if you are testing the User#login method. You should not set a stub if you are trying to test the logic of the method being stubbed. Instead, use a real model instance, perhaps using a factory, and omit the allow step.

zetetic
  • 47,184
  • 10
  • 111
  • 119
  • Why am i getting this error... Failure/Error: expect(user.login).to eq(expected_results) Double "user" received :login with unexpected arguments expected: ({:email=>"test@test.com", :password=>"123", :code=>"0"}) got: (no args) Please stub a default value first if message might be received with other args as well. – UnderTaker Aug 12 '14 at 20:56
  • The user.login hits the api and returns me the above response, so i thought of doing this way? Is this a fine approach and also why am i getting the above error. – UnderTaker Aug 12 '14 at 21:00
  • It sounds like you need to mock the API response, not the `login` method call. Why not post the relevant code from the User model? – zetetic Aug 12 '14 at 21:01
  • pastie.org/9468099 It contains my model class – UnderTaker Aug 12 '14 at 21:03
  • It is something to worry/concern if i do this in the above way? – UnderTaker Aug 12 '14 at 21:13
  • I see you have created this model using `active_rest_client`, about which I know nothing. I'd take a step back and think about what you are trying to achieve, perhaps take a look at how the gem author writes tests: https://github.com/whichdigital/active-rest-client/blob/master/spec/lib/request_spec.rb. Then come back and ask another question if you still need help. – zetetic Aug 12 '14 at 21:17
  • 1
    It depends what you stub. I can't say more without knowing the goal of your tests. Take the time to read the link I posted above--it shows how the author of `active_rest_client` tested the gem, and should be helpful in deciding how to design your test strategy. – zetetic Aug 12 '14 at 21:28