【问题标题】:Testing that a method was called on a Sinatra request测试在 Sinatra 请求上调用了一个方法
【发布时间】:2022-01-27 14:17:20
【问题描述】:

希望有人可以帮助我提供一些基本的 Sinatra 测试帮助...

我有一个玩具 sinatra 应用程序,它实现了这个基本端点,它调用了一个同名的方法:

  get '/hello' do
    hello
  end 

  def hello
    "hello"
  end 

然后我有这 3 个规格。第一次和第三次通过,但第二次失败:

  context 'get /hello' do
    let(:app) { App.new! }

    it 'responds to hello' do
      expect(app).to respond_to :hello
    end

    it 'calls hello' do
      expect(app).to receive(:hello)
      get '/hello'
    end 

    it 'returns hello' do
      let(:response) { get '/hello' }

      expect(response.status).to eq 200
      expect(response.body).to eq "hello"
    end

  end 

没有被调用的错误:

 expected: 1 time with any arguments
 received: 0 times with any arguments

第一个规范证明该方法存在,第三个规范证明它实际上是根据 rspec 调用该方法。我不确定要使第二个规范正常工作我缺少什么

【问题讨论】:

  • 我怀疑你的主题是错误的。什么是将消息发送app?它可能不是您规范中的 App 实例。
  • 我正在使用Rack::Test::Methods,所以在“获取”时,它会调用将其发送到应用程序。为了记住事情,我也开始使用let(:app) { App.new! },因此这个上下文只有一个 App 实例,但仍然没有变化。
  • 我怀疑这不起作用的原因是当Sinatra handles a request it dups itself 时,一个新的实例负责每个请求。被模拟的 app 实例与实际调用方法的实例不同。

标签: ruby api testing rspec sinatra


【解决方案1】:

由于您使用的是Rack::Test,因此您需要提供一个名为app 的方法,该方法返回要模拟的应用程序,而不是使用letApp.new!。像这样的:

RSpec.describe 'app' do
  include Rack::Test::Methods

  def app
    Sinatra::Application
  end
  
  context 'get /hello' do
    before { get '/hello' }
    
    it { expect(last_response.status).to eq(200) }
    it { expect(last_response.body).to eq('hello') }
  end

有关app 方法的更多信息可以在Sinatra testing docs 中找到。

FWIW 我不会为您示例中的前两个测试编写机架级测试。它不必要地将实现与测试耦合在一起。我会直接测试hello 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2023-03-28
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多