使用 rspec 测试 Rails 模型方法

问题描述 投票:0回答:3

我很困惑为什么这个测试不起作用。它仅在我将返回值添加到存根

bar
方法时才有效。但是,预计不会有返回值,所以我只想测试
bar
foo
内被调用。

class Event < ApplicationRecord
  def foo
    bar
  end
end

此测试无效。

describe Event, type: :model do
  it 'calls bar' do
    event = create(:event)
    
    allow(event).to receive(:bar)

    expect(event.foo).to receive(:bar)
  end
end


Error message:
Failure/Error: expect(event.foo).to receive(:bar)
     
  (nil).bar(*(any args))
     expected: 1 time with any arguments
     received: 0 times with any arguments

当我更改测试以添加返回值时,测试有效。

describe Event, type: :model do
  it 'calls bar' do
    event = create(:event)
    
    allow(event).to receive(:bar).and_return(true)

    expect(event.foo).to eq(true)
  end
end
ruby-on-rails rspec
3个回答
0
投票

这张图有很多地方不对

让我们从方法开始:

class Event < ApplicationRecord
  def foo
    bar
  end
end

当您调用

Event.new.foo
时,您是在
#bar
上调用
self
,这是Event的实例。不在方法上
foo
.

如果你这样做

expect(event.foo).to receive(:bar)
你设置了对方法返回值的期望,这当然是行不通的。

如果你想测试调用 foo 调用 bar 你可以使用

expect(obj).to recieve :method_name
如果你想事先设置期望值:

describe Event, type: :model do
  it 'calls bar' do
    event = create(:event)
    expect(event).to receive(:bar)
    event.foo
  end
end

请注意,除非您想存根该方法,否则不必使用

allow(event).to receive(:bar)
expect(event).to receive(:bar)
包装方法,以便 RSpec 可以跟踪对该方法的调用。

除非调用预期的方法,否则该示例将失败。

或者如果您更喜欢安排、行动、断言模式,您可以使用间谍:

describe Event, type: :model do
  it 'calls bar' do
    # arrange
    event = create(:event) 
    allow(event).to receive(:bar) 
    # act
    event.foo
    # assert
    expect(foo).to have_recieved(:bar)
  end
end

-1
投票

不幸的是,这是错误的测试方式。您不需要模拟您的方法。就叫它吧

这是正确的做法。

describe Event, type: :model do
  describe '#foo' do
    subject { event.foo }
    let(:event) { create(:event) }

    it 'does something' do
      expect(subject).to eq(true)
    end
  end
end

-1
投票

发布我的问题后找到答案:

describe Event, type: :model do
  it 'calls bar' do
    event = create(:event)
    
    allow(event).to receive(:bar)

    expect(event).to receive(:bar)

    event.foo
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.