Rails 和 minitest/spec 中的 NoMethodError <fixture name>
NoMethodError <fixture name> in Rails and minitest/spec
没有 minitest/spec,测试看起来像这样,并且加载了 my_engine_customers
个固定装置(一切正常):
my_engine/test/models/my_engine/customer_test.rb
是
require 'test_helper'
module MyEngine
class CustomerTest < ActiveSupport::TestCase
test "alex is id 5" do
assert my_engine_customers(:alex).id, 5
end
end
end
将require 'minitest/autorun'
加到test/test_helper.rb
后,再
转换以上测试:
require 'test_helper'
describe MyEngine::Customer do
let(:alex) { my_engine_customers(:alex) } # error here (error shown below)
it "alex is id 5" do
assert alex.id, 5
end
end
我收到这个错误:
NoMethodError: undefined method `my_engine_customers' for
#<#<Class:0x007fb63e8f09e8>:0x007fb63e81b068>
使用 minitest/spec 时如何访问固定装置?
当您使用规范 DSL 时,您会得到一个 Minitest::Spec
对象到 运行 您的测试。但是 Rails fixtures 和数据库事务仅在 ActiveSupport::TestCase
中可用,或者像 ActionController::TestCase
一样从它继承的测试 类 中可用。所以你需要的是规范 DSL 使用 ActionSupport::TestCase
进行测试的某种方式。
这有两个步骤,首先 ActiveSupport::TestCase
需要支持规范 DSL。您可以通过将以下代码添加到 test_helper.rb
文件来执行此操作:
class ActiveSupport::TestCase
# Add spec DSL
extend Minitest::Spec::DSL
end
(您知道 ActiveSupport::TestCase.describe
存在吗?如果您计划进行嵌套描述,您可能希望在添加规范 DSL 之前删除该方法。)
其次,您需要告诉规范 DSL 使用 ActiveSupport::TestCase
。为此,规范 DSL 添加了 register_spec_type
。因此,还要将以下内容添加到您的 test_helper.rb
文件中:
class ActiveSupport::TestCase
# Use AS::TestCase for the base class when describing a model
register_spec_type(self) do |desc|
desc < ActiveRecord::Base if desc.is_a?(Class)
end
end
这将查看描述的主题,如果它是 ActiveRecord 模型,它将使用 ActiveSupport::TestCase
而不是 Minitest::Spec
来 运行 测试。
如您所料,当您尝试将规范 DSL 用于控制器和其他类型的测试时,会遇到许多其他陷阱。 IMO 最简单的方法是在 test_helper.rb
文件中添加对 minitest-rails 和 require "minitest/rails"
的依赖。 minitest-rails 完成所有这些配置以及更多工作,使过程更加顺畅。 (再次,IMO。)
有关详细信息,请参阅我的 blaurgh post Adding Minitest Spec in Rails 4。
没有 minitest/spec,测试看起来像这样,并且加载了 my_engine_customers
个固定装置(一切正常):
my_engine/test/models/my_engine/customer_test.rb
是
require 'test_helper'
module MyEngine
class CustomerTest < ActiveSupport::TestCase
test "alex is id 5" do
assert my_engine_customers(:alex).id, 5
end
end
end
将require 'minitest/autorun'
加到test/test_helper.rb
后,再
转换以上测试:
require 'test_helper'
describe MyEngine::Customer do
let(:alex) { my_engine_customers(:alex) } # error here (error shown below)
it "alex is id 5" do
assert alex.id, 5
end
end
我收到这个错误:
NoMethodError: undefined method `my_engine_customers' for
#<#<Class:0x007fb63e8f09e8>:0x007fb63e81b068>
使用 minitest/spec 时如何访问固定装置?
当您使用规范 DSL 时,您会得到一个 Minitest::Spec
对象到 运行 您的测试。但是 Rails fixtures 和数据库事务仅在 ActiveSupport::TestCase
中可用,或者像 ActionController::TestCase
一样从它继承的测试 类 中可用。所以你需要的是规范 DSL 使用 ActionSupport::TestCase
进行测试的某种方式。
这有两个步骤,首先 ActiveSupport::TestCase
需要支持规范 DSL。您可以通过将以下代码添加到 test_helper.rb
文件来执行此操作:
class ActiveSupport::TestCase
# Add spec DSL
extend Minitest::Spec::DSL
end
(您知道 ActiveSupport::TestCase.describe
存在吗?如果您计划进行嵌套描述,您可能希望在添加规范 DSL 之前删除该方法。)
其次,您需要告诉规范 DSL 使用 ActiveSupport::TestCase
。为此,规范 DSL 添加了 register_spec_type
。因此,还要将以下内容添加到您的 test_helper.rb
文件中:
class ActiveSupport::TestCase
# Use AS::TestCase for the base class when describing a model
register_spec_type(self) do |desc|
desc < ActiveRecord::Base if desc.is_a?(Class)
end
end
这将查看描述的主题,如果它是 ActiveRecord 模型,它将使用 ActiveSupport::TestCase
而不是 Minitest::Spec
来 运行 测试。
如您所料,当您尝试将规范 DSL 用于控制器和其他类型的测试时,会遇到许多其他陷阱。 IMO 最简单的方法是在 test_helper.rb
文件中添加对 minitest-rails 和 require "minitest/rails"
的依赖。 minitest-rails 完成所有这些配置以及更多工作,使过程更加顺畅。 (再次,IMO。)
有关详细信息,请参阅我的 blaurgh post Adding Minitest Spec in Rails 4。