Ruby on rails RSPEC:如何测试控制器操作是否返回JSON Web令牌

Ruby on rails RSPEC:如何测试控制器操作是否返回JSON Web令牌,ruby-on-rails,rspec,jwt,Ruby On Rails,Rspec,Jwt,我正在使用Desive和JWT对我正在编写的项目中的用户进行身份验证。我很难弄明白如何编写一个有用的测试来期望JWT响应.body(因为每个测试都是加密的) 我能想到的唯一一件事就是测试它们的结构是否应该是JWT(3段,。分隔字符串) 是否有人遇到过测试随机/散列返回的问题,并提出了更好的解决方案 describe SessionTokensController, type: :controller do let(:current_user) { FactoryGirl.create(:us

我正在使用Desive和JWT对我正在编写的项目中的用户进行身份验证。我很难弄明白如何编写一个有用的测试来期望JWT
响应.body
(因为每个测试都是加密的)

我能想到的唯一一件事就是测试它们的结构是否应该是JWT(3段,
分隔字符串)

是否有人遇到过测试随机/散列返回的问题,并提出了更好的解决方案

describe SessionTokensController, type: :controller do
  let(:current_user) { FactoryGirl.create(:user) }

  before(:each) do
    sign_in current_user
  end

  describe '#create' do
    it 'responds with a JWT' do
      post :create
      token = JSON.parse(response.body)['token']

      expect(token).to be_kind_of(String)
      segments = token.split('.')
      expect(segments.size).to eql(3)
    end
  end
end

这取决于你到底想测试什么

如果只想测试返回的令牌是否存在且有效,则可以执行以下操作:

it 'responds with a valid JWT' do
  post :create
  token = JSON.parse(response.body)['token']

  expect { JWT.decode(token, key) }.to_not raise_error(JWT::DecodeError)
end
尽管验证令牌包括的声明似乎更有用:

let(:claims) { JWT.decode(JSON.parse(response.body)['token'], key) }

it 'returns a JWT with valid claims' do
  post :create
  expect(claims['user_id']).to eq(123)
end

在后一个示例中,您可以验证JWT中包含的确切声明。

您需要调用
JWT.decode token,nil,false
,否则调用将导致错误@Weggino解码未签名令牌并不是这里真正的练习,除非您使用未签名令牌(您确实不应该这么做)。。。但是你是对的,我在
decode
方法调用中缺少了关键参数。谢谢
    let(:user) { create(:user, password: "123456") }

      describe "POST authenticate_user" do
        context "with a valid password" do
          it "authenticates successfully" do
            post :authenticate_user, params:{email: user.email, password: "123456"}, format: :json
            parsed_body = JSON.parse(response.body)
            # binding.pry
            expect(parsed_body.keys).to match_array(["auth_token", "user"])
            expect(parsed_body['user']['email']).to eql("joe@gmail.com")
            expect(parsed_body['user']['id']).to eql(user.id)
          end

          it "authentication fails" do
            post :authenticate_user, params:{email: user.email, password: "123456789"}, format: :json
            parsed_body = JSON.parse(response.body)
            expect(parsed_body['errors'][0]).to eql("Invalid Username/Password")
          end
        end
      end