这是辅助模块:
module SendingMailHelper
def send_mail(subject, body)
to_email_id = " abc@gmail.com"
cc_email_id = "def@gmail.com"
html_message = %{<html><body>#{body}</body></html>}
flag=false
while(!flag) do
flag = system %{echo "#{html_message}" | mutt -e "set content_type=text/html" -s "#{subject}" #{cc_email_id} -- #{to_email_id}}
end
flag
end
end
我编写规范的方式如下,但它不起作用:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe SendingMailHelper do
it "test something" do
html_message = %{<html><body>www.google.com</body></html>}
to_email_id = " abc@gmail.com"
cc_email_id = "def@gmail.com"
subject = "test e-mail"
SendingMailHelper.expects(:system).with(%{echo "#{html_message}" | mutt -e "set content_type=text/html" -s "#{subject}" #{cc_email_id} -- #{to_email_id}}).returns(true).once
helper.send_mail("test e-mail","www.google.com").should==true
end
end
收到以下错误:
SendingMailHelper test something
Failure/Error: SendingMailHelper.expects(:system).with(%{echo "#{html_message}" | mutt -e "set content_type=text/html" -s "#{subject}" #{cc_email_id} -- #{to_email_id}}).returns(true).once
Mocha::ExpectationError:
not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, not yet invoked:
我也想以这样的方式模仿它,模拟mutt两次返回false
并在第三次调用中返回true以测试重试机制。有没有办法做到这一点?
答案 0 :(得分:0)
require_relative './sending_mail_helper'
require 'rspec/mocks/standalone'
describe SendingMailHelper do
let(:helper) do
Class.new do
include SendingMailHelper
attr_reader :system_calls
def system(*args)
@system_calls ||= []
@system_calls << args
[false, false, true][(@system_calls.size - 1) % 3]
end
end.new
end
it "test the call is made" do
html_message = %{<html><body>www.google.com</body></html>}
to_email_id = " abc@gmail.com"
cc_email_id = "def@gmail.com"
subject = "test e-mail"
helper.send_mail("test e-mail","www.google.com")
# check it was called once
helper.system_calls.size should eq 1
# check it was called with appropriete arguments
helper.system_calls.last.first.should eq %{echo "#{html_message}" | mutt -e "set content_type=text/html" -s "#{subject}" #{cc_email_id} -- #{to_email_id}}
end
it "retries the command until it succeded" do
helper.send_mail("test e-mail","www.google.com")
helper.system_calls.size.should eq 3
end
end
你可以使用这个小黑客。实际上,这几乎就是存根和模拟监视函数调用。使用rspec-mock工具运行测试失败严重。我个人建议你不要测试系统调用它实际上会在你的测试中带来很多耦合并且实现并使代码更难维护。另一个建议我会给你使用一些ruby gem来处理你试图使用sys调用命令的电子邮件功能。最后抱歉使用shoulds
但是我的计算机上有旧的rspec gem,并且缺少新的expect
语法。