如何在Sinatra控制器中测试方法?

时间:2015-10-07 19:38:27

标签: ruby rspec sinatra

我正在尝试测试使用Rspec在我的Sinatra控制器中调用方法。我正在为一个迷你项目克隆Twitter,并希望确保每次新用户注册时,都会发送一封电子邮件。

这可以使用Mailgun,一种红宝石,一旦新用户注册,就会发送电子邮件。

问题在于测试。我在控制器中编写了一个名为send_mail的方法,只有在用户注册时才会被调用。忽略此方法的内容,对于此问题而言,它们并不重要。只知道它有效。

def send_email
  RestClient::Request.execute(
  url: "https://api:key-7af11fe0adc2a642e55d33744117e7d2"\
  "@api.mailgun.net/v3/sandbox1aad2b9369f348018e3b435a1026927c.mailgun.org/messages",
  :method => :post,
  :payload => {
  :from => 'Mailgun Sandbox <postmaster@sandbox1aad2b9369f348018e3b435a1026927c.mailgun.org>',
  :sender => 'Mailgun Sandbox <postmaster@sandbox1aad2b9369f348018e3b435a1026927c.mailgun.org>',
  :to => params[:email],
  :subject => "Welcome to Chitter",
  :text => "Welcome to Adrian's awesome Chitter site. " + params[:username] + ".Get Chittering!",
  :multipart => true
  },
  :headers => {
    :"h:X-My-Header" => "www/mailgun-email-send"
  },
  :verify_ssl => false
  )
end

此方法(send_email)在下面第8行的post请求中被调用。

  post '/users' do
@user = User.create(email: params[:email],
            username: params[:username],
            password: params[:password],
            password_confirmation: params[:password_confirmation])

if @user.save
  session[:user_id] = @user.id
  send_email
  redirect '/peeps'
else
  flash.now[:errors] = @user.errors.full_messages
  erb :'users/new'
end
end

我写了一堆测试,一个测试应用程序甚至响应方法,第二个测试新用户注册时调用send_email方法。

describe Chitter do
include Rack::Test::Methods

def app
 Chitter.new!
end

it 'has send_email method' do
 expect(app).to respond_to :send_email
end

it 'sends a message to the user when user signs up' do
 allow_any_instance_of(RestClient::Request).to receive(:execute).with(any_args)
 post '/users', params={email: "example@email.com", 
                      username: "Adrian17", 
                      password: "adrian1", 
                      password_confirmation: 'adrian1'}
 expect(app).to have_received(:send_email)
end

我们的第一次测试通过(应用程序应该响应send_email)但第二次没有。我们得到的错误消息是该方法尚未被删除。

Failure/Error: expect(app).to have_received(:send_email)
   #<Chitter:0x007f959e8e3088> expected to have received send_email, but that object is not a spy or method has not been stubbed.

花了很多时间在这上面,不同的眼睛让它一试,但我们所做的一切都没能使这个测试通过。关于我们可能出错的地方的任何指导?

1 个答案:

答案 0 :(得分:0)

it 'sends a message to the user when user signs up' do
  allow_any_instance_of(RestClient::Request).to receive(:execute).with(any_args)
  expect(app).to receive(:send_email)
  post '/users', params={email: "example@email.com", 
                      username: "Adrian17", 
                      password: "adrian1", 
                      password_confirmation: 'adrian1'}
end

那会让你飞的!