[英]ControllerMacros method not being loaded by RSpec
I've added a ControllerMacro
but the method isn't being made available in my specs. 我添加了一个
ControllerMacro
但我的规格中没有提供该方法。 My specs will fail with: 我的规格将失败:
NoMethodError: undefined method `attributes_with_foreign_keys' for FactoryGirl:Module
I'm trying to do this following this discussion on Github. 我正在尝试在Github上讨论之后这样做。 I've looked at other similar questions but most point at using
config.include ControllerMacros, :type => :controller
instead of config.extend ControllerMacros, :type => :controller
which I'm doing already. 我看过其他类似的问题,但大多数都指向使用
config.include ControllerMacros, :type => :controller
而不是config.extend ControllerMacros, :type => :controller
我已经在做了。
Now I know that the controller_macros.rb
file is being loaded upon starting the test as I've run the specs through RubyMine's debugger but why the method isn't available is beyond me! 现在我知道在启动测试时正在加载
controller_macros.rb
文件,因为我通过RubyMine的调试器运行规范,但为什么这个方法不可用超出了我!
spec_helper.rb
require 'simplecov'
SimpleCov.start 'rails'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'email_spec'
require 'rspec/autorun'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
config.include ControllerMacros, :type => :controller
config.include FactoryGirl::Syntax::Methods
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
spec/support/macros/controller_macros.rb
module ControllerMacros
def attributes_with_foreign_keys(*args)
FactoryGirl.build(*args).attributes.delete_if do |k, v|
["id", "type", "created_at", "updated_at"].member?(k)
end
end
end
This example controller spec: 此示例控制器规范:
describe "POST create" do
describe "with valid params" do
it "creates a new Course" do
expect {
#post :create, course: FactoryGirl.build(:course)
post :create, course: FactoryGirl.attributes_with_foreign_keys(:course)
}.to change(Course, :count).by(1)
end
The macro you defined is a method within a module. 您定义的宏是模块中的方法。 You asked Rspec to include the module, so the method is available to Rspec's instance, which should be used similar to
describe
, it
etc. 您要求Rspec包含该模块,因此该方法可用于Rspec的实例,该实例应与
describe
, it
等类似。
However, you used this method as a FactoryGirl's class method. 但是,您将此方法用作FactoryGirl的类方法。 Obviously this is not working.
显然这不起作用。
It looks you want to have a convenient method to quickly build a set of pre-defined attributes of a model in a special case. 在特殊情况下,您希望有一种方便的方法来快速构建模型的一组预定义属性。
This logic is better not to be a "macro", because it's better to use FactoryGirl as a centralized place to store all logic about models. 这种逻辑最好不要成为“宏”,因为最好将FactoryGirl用作存储模型所有逻辑的集中位置。
So, the most convenient way is, beyond your normal factories, define a special factory for this case, say foo
, with all association and other logic you need inside it, and inherit from other normal factory. 因此,最方便的方法是,除了正常的工厂之外,为这种情况定义一个特殊的工厂,比如
foo
,它包含你需要的所有关联和其他逻辑,并从其他正常工厂继承。
If it's name is foo
, then you can easily build a hash of foo's attributes like FactoryGirl.attributes_for :foo
如果它的名字是
foo
,那么你可以轻松地建立一个foo的属性的散列,如FactoryGirl.attributes_for :foo
Instead of calling: 而不是打电话:
post :create, course: FactoryGirl.attributes_with_foreign_keys(:course)
Just call: 只需致电:
post :create, course: attributes_with_foreign_keys(:course)
Took advice from @Billy Chan answer. 从@Billy Chan的回答中得到建议。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.