Iai*_*ain 4 ruby tdd ruby-on-rails minitest
如果我使用RSpec,我可以测试是否正在调用方法:
expect(obj).to receive(:method)
Run Code Online (Sandbox Code Playgroud)
MiniTest中的等价物是什么?我有一个模型,Post它有一个before_validation运行方法的回调create_slug.在我的测试中,test/models/post_test.rb我想确保create_slug在调用时调用该方法post.save.
Minitest :: Spec文档说我可以使用一种方法must_send来检查方法是否被调用.但是,当我尝试时,@post.must_send :create_slug我收到以下错误:
NoMethodError: undefined method `must_send' for #<Post:0x007fe73c39c648>
Run Code Online (Sandbox Code Playgroud)
我在我的test_helper.rb文件中包含Minitest :: Spec :
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'minitest/spec'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
# Add more helper methods to be used by all tests here...
end
Run Code Online (Sandbox Code Playgroud)
我的测试摘录:
describe Post do
before do
@post = FactoryGirl.build(:post)
end
describe "when saving" do
it "calls the create_slug method before validation" do
@post.must_send :create_slug
@post.save
end
end
end
Run Code Online (Sandbox Code Playgroud)
blo*_*age 10
你在这里要求的是部分嘲笑.这意味着你有一个真实的对象,你想模拟一个方法并验证它被调用.Minitest :: Mock不支持开箱即用的部分模拟,但我会尽力向您展示如何实现这一目标.在"部分模拟"上进行一两次搜索,看看人们对此有什么看法.
支持部分模拟的最简单方法是使用不同的模拟库,如Mocha.只需添加gem "mocha"到您的Gemfile中就可以了.
describe Post do
before do
@post = FactoryGirl.build(:post)
end
describe "when saving" do
it "calls the create_slug method before validation" do
@post.expects(:create_slug).returns(true)
@post.save
end
end
end
Run Code Online (Sandbox Code Playgroud)
但是如果你真的想使用Minitest :: Mock,有一种方法可以让它发挥作用.它需要一个新的模拟对象并使用ruby重新定义该create_slug方法.哦,还有全局变量.
describe Post do
before do
@post = FactoryGirl.build(:post)
end
describe "when saving" do
it "calls the create_slug method before validation" do
$create_slug_mock = Minitest::Mock.new
$create_slug_mock.expect :create_slug, true
def @post.create_slug
$create_slug_mock.create_slug
end
@post.save
$create_slug_mock.verify
end
end
end
Run Code Online (Sandbox Code Playgroud)
哇.那很难看.看起来像一个疏忽,对吗?Minitest为什么会让部分嘲讽如此困难和丑陋?这实际上是一个不同问题的症状.问题不是"我如何使用部分嘲讽?",问题是"我如何测试代码的预期行为?" 这些测试正在检查实施情况.如果重命名create_slug方法怎么办?或者,如果您将创建slug的机制从回调更改为其他内容,该怎么办?这将要求此测试也发生变化.
相反,如果您的测试只检查了预期的行为呢?然后,您可以重构代码并更改您的实现,而不会破坏测试.那会是什么样的?
describe Post do
before do
@post = FactoryGirl.build(:post)
end
describe "when saving" do
it "creates a slug" do
@post.slug.must_be :nil?
@post.save
@post.slug.wont_be :nil?
end
end
end
Run Code Online (Sandbox Code Playgroud)
现在我们可以自由更改实现而无需更改测试.测试涵盖了预期的行为,因此我们可以重构和清理代码而不会破坏所述行为.人们问为什么Minitest不支持部分嘲笑.这就是为什么.你很少需要它们.
| 归档时间: |
|
| 查看次数: |
3806 次 |
| 最近记录: |