繁体   English   中英

在RSpec中使用factory_bot(以前为factory_girl)在Rails中进行测试时,未定义的方法“ first”

[英]When using factory_bot (formerly factory_girl) with RSpec to test in Rails, undefined method “first”

我有一个Rspec测试,它使用factory_bot创建实例。 除在视图中使用一种方法外,测试均通过。

这是正在测试的代码:

def order_confirm_email(id, items, order, address, coupon)
    @user = User.find(id)
    @items = items
    @order = order
    @address = address
    if coupon == nil
      @coupon = ''
    else
      @coupon = coupon.discount
    end

    mail(to: @user.email, subject: 'Order completed')
  end

这是测试:

it 'sends an email upon checkout process completion' do
      user    = create(:user)
      items   = create(:base_item)
      order   = create(:base_item)
      address = create(:address)
      coupon  = create(:coupon)

      expect(orderConfirmationMail.subject).to eq('Order completed')
    end

到现在为止还挺好。 但是,当其中一个视图尝试访问第一个实例时,如下所示:

<h1>Order id - <%= @order.first.id %></h1>

然后,我收到以下错误:

Failures:

  1) UserMailer user_emails sends an email upon checkout process completion
     Failure/Error: <!-- <h1>Order id - <%= @order.first.id %></h1> -->

     ActionView::Template::Error:
       undefined method `first' for 3:Fixnum

根据我的理解,由于我使用create而不是build ,因此实例应该是持久的。 但是显然这没有发生。 除非万不得已,否则不能更改视图。 我该如何解决?

更新1:

这是order_items.rb工厂文件:

FactoryBot.define do
  factory :base_item, class: OrderItem do
    item_name_en "Sample Item"
    item_link "http://www.foo.com"
    qty 5
    available_qty 100
    item_price 10
    seller_name "foo"
    status "foo"

    foo_item_id "123456"
    foo_id "654321"
  end

  factory :order_item1, parent: :base_item do
    foo_item_id "123456"
    foo_seller_id "654321"
    association :order
  end

  factory :order_item2, parent: :base_item do
    foo_item_id "123457"
    foo_seller_id "654321"
  end

  factory :order_item3, parent: :base_item do
    foo_item_id "123458"
    foo_seller_id "654322"
  end
end

更新2:

在编写另一个测试时,我遇到了类似的问题。 我收到以下错误:

Failures:

  1) UserMailer user_emails sends an email upon abandoned cart
     Failure/Error: <% @items.each do |item| %>

     ActionView::Template::Error:
       undefined method `each' for 1:Fixnum

这似乎表明这与一种方法本身无关,而与运行RSpec时在视图中插入的Ruby引发错误有关。 这将问题泛化,并希望使其更容易解决。

没问题,在规范的前面,我加入了这一行,因为我在另一项测试中成功使用了相同的格式,所以我知道这行正常

let(:orderConfirmationMail) { UserMailer.order_confirm_email(1,2,3,4,nil) }

在那里。 如果您从一开始就加入了这一行,那么您的问题将在两秒钟内得到解答。

考虑order_confirm_email的签名

def order_confirm_email(id, items, order, address, coupon)

您为什么认为order设置为3? 因为你这样通过!

谜团已揭开。

抱歉,我不知道。 我会看一下您的OrderItem模型,我也不明白为什么要使用@order.first因为那只是1个对象。 对我来说可能有意义@orders.first而不是@order.first 当事情不道理rails ,很难构建应用程序。 orderitem应该是两个不同的模型,我们使用order_items在两个不同的模型之间建立联接

一个订单可以有多个或只有一个项目,您可以确定关系。

使用rspec可以调试,也可以在rails c test环境中测试工厂。 在那里,您可以检查create(:base_item)FactoryGirl.create(:base_item)

我认为这应该是一个对象,所以我不明白为什么它在说undefined method 'first' for 3:Fixnum

也许您的factory不是我们期望的

但是您可以通过在工厂的控制台中进行调试和测试来了解这一点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM