模拟模型及其方法

时间:2014-08-13 07:11:40

标签: ruby-on-rails ruby ruby-on-rails-3 unit-testing rspec

有谁能告诉我我的方法是否合适?

我想知道我们正在使用的api是按设计工作的,当它发生变化时,我们知道这已经改变,而无需深入研究所有code逻辑。我们将提供一组参数,我们期望得到一定的结果,以便我的单元测试运行良好。

User.login({email: username, password: password);

我的模型中的上述方法实际上击中了API并返回了一个响应。我想检查我的Model的登录方法是否按预期工作。

以下是我的approach

我在我的模型中使用必需的参数和预期响应来存储我的登录方法,以避免命中api然后期望login方法derive相同的响应。 我正在使用ActiveRestClient。

以下是我的模特

class User << ActiveRestClient::Base
  get :all, '/user'
  get :find, '/user/:id'
end

以下是我的规格

require 'spec_helper'

describe User do 

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

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

    it "should sign in with valid input" do 
      allow(User).to receive(:login).with({email: username, password: 
           password}).and_return(response)
      expect(User.login({email: username, password: passwor})).to eq(response)
    end

  end

end

有谁能告诉我我的方法是否合适?

1 个答案:

答案 0 :(得分:0)

不,我很抱歉,你的方法并不好。因为它不测试我们代码的单行。您的规范测试的唯一事情是User.login存根返回您告诉它返回的内容。

如果您想通过存根方法来加速您的规格,那么您应该在方法中查找触及数据库的调用。在下面的示例中有类似User.find_by_email的内容(我猜你在login方法中做了类似的事情)。

此外,如果emailpassword不匹配,您可能希望发生规范。

describe User do 
  describe 'login' do
    let(:username)  { "test@test.com" }
    let(:password)  { "password" }
    subject(:login) { User.login(email: username, password: password) }

    context 'when user do not exists' do
      before { allow(User).to receive(:find_by_email).and_return(nil) }

      it 'returns nil' do
        expect(login).to be_nil
      end
    end

    context 'when user exists' do
      before do
        allow(User).to receive(:find_by_email).with(username).and_return(user)
      end

      context 'when password does not match' do
        let(:user) { User.new(:password => 'wrong password') }

        it 'returns nil' do
          expect(login).to be_nil
        end
      end

      context 'when password matches' do
        let(:user) { User.new(:password => password, :generate_token => 123) }

        it 'returns a json containing the signin token' do
          expect(login).to eq "{'token':'123'}"
        end
      end
    end
  end
end

由于我不知道你的login方法究竟做了什么,所以上面的所有规范都只是基于假设,并且非常希望不通过你的实现。但我希望你明白这一点。