Ruby on rails Rspec在“上失败”;让我们;s

Ruby on rails Rspec在“上失败”;让我们;s,ruby-on-rails,testing,rspec,Ruby On Rails,Testing,Rspec,我有一个邮递员 class MyMailer < ActionMailer::Base def send1(a, b, c) #..... mail(....).deliver end def send2(a, b, c) #..... mail(....).deliver end end 因此,在大多数情况下,由于错误而失败的情况下,应发送一封电子邮件,期望1得到2,并且应发送一封电子邮件,期望1得到4或0 有时数字是不同的(得到0-4

我有一个邮递员

class MyMailer < ActionMailer::Base
  def send1(a, b, c)
    #.....
    mail(....).deliver
  end

  def send2(a, b, c)
    #.....
    mail(....).deliver
  end
end
因此,在大多数情况下,由于错误而失败的情况下,应发送一封电子邮件,期望1得到2,并且应发送一封电子邮件,期望1得到4或0 有时数字是不同的(得到0-4)。我试着这样做:

  let!(:send1_email) { MyMailer.send1 a, b, c }
  let!(:send1_emai2) { MyMailer.send2 d, e, g }
但它也失败了

Failure/Error: expect(MyMailer.deliveries.count).to eq(1)

       expected: 1
            got: 4
我想知道为什么

以前我用过
:所有
@变量
,一切都很好(没有错误)

相同的错误:

   it "should send an email" do
      expect(MyMailer.deliveries.count).to eq(1)
      MyMailer.deliveries.clear
    end

   it "should send an email2" do
     expect(MyMailer.deliveries.count).to eq(1)
     MyMailer.deliveries.clear
   end

如文件中所述

使用let定义已记忆的辅助对象方法。该值将被缓存 跨同一示例中的多个调用,但不跨示例


另外,我确信您知道rspec以随机顺序运行示例,这意味着其他示例调用mail sending let()帮助程序,这意味着当它到达您的测试时,套件已经发送了4封电子邮件,使您的测试失败。您不应该依赖于定义测试的顺序。您应该确保在示例之前擦洗并清理测试数据。

如文档中所述

使用let定义已记忆的辅助对象方法。该值将被缓存 跨同一示例中的多个调用,但不跨示例


另外,我确信您知道rspec以随机顺序运行示例,这意味着其他示例调用mail sending let()帮助程序,这意味着当它到达您的测试时,套件已经发送了4封电子邮件,使您的测试失败。您不应该依赖于定义测试的顺序。在示例之前,您应该确保您的测试数据已被擦洗干净。

let和
let之间存在差异

let
仅在调用时实例化,换句话说,rspec在使用变量之前不会查看
let
块内部

let(:send1_email2) { MyMailer.send2 d, e, g }
it 'testing' do
  # email not sent yet because we use let without bang
  expect(MyMailer.deliveries.count).to eq(0)

  send1_email2.call_a_method
  # now email is sent since we used the variable send1_email2
  expect(MyMailer.deliveries.count).to eq(1)
end
let被实例化,就好像它是
块之前的一个

let!(:send1_email2) { MyMailer.send2 d, e, g }
it 'testing' do
  # before we do anything the email is sent because we used let with a bang
  expect(MyMailer.deliveries.count).to eq(1)
end

另外,不要在(:all){MyMailer.deliveries.clear}
之后使用
,而是在{MyMailer.deliveries.clear}
之后使用
,否则您的示例之间的计数器将不会被清除

让之间存在差异

let
仅在调用时实例化,换句话说,rspec在使用变量之前不会查看
let
块内部

let(:send1_email2) { MyMailer.send2 d, e, g }
it 'testing' do
  # email not sent yet because we use let without bang
  expect(MyMailer.deliveries.count).to eq(0)

  send1_email2.call_a_method
  # now email is sent since we used the variable send1_email2
  expect(MyMailer.deliveries.count).to eq(1)
end
let被实例化,就好像它是
块之前的一个

let!(:send1_email2) { MyMailer.send2 d, e, g }
it 'testing' do
  # before we do anything the email is sent because we used let with a bang
  expect(MyMailer.deliveries.count).to eq(1)
end

另外,不要在(:all){MyMailer.deliveries.clear}
之后使用
,而是在{MyMailer.deliveries.clear}
之后使用
,否则您的计数器在示例之间不会被清除

请发布实际的回溯和错误。@TanelSuurhans,给您。正如我所说,“得到”有时会有所不同。请发布实际的回溯和错误。@TanelSuurhans,给你。正如我所说,“GET”有时会有所不同。我想说的是,您需要在每次发送后/每次依赖它的测试之前清除交付内容。只有前两个依赖它,并且失败。正如我前面所指出的,您编写的第一个测试并不是第一个运行的测试。您的示例是以随机顺序运行的,因此您首先编写的测试可能很容易成为最后一个运行的测试,这意味着其他测试已经发送了多封电子邮件。毕竟,如果第一个测试将在第二个测试之后运行呢?我给
let(:send1_email1){MyMailer.send1 a,b,c}
每个
description
只打一次电话,检查
MyMailer.deliveries.count
也打一次电话。我在每个描述中都清除了MyMailer.deliveries.clear。
套件已经发送了4封电子邮件,让您的测试失败
-这是不可能的,因为它们被调用的次数正好是测试的2次-在第一次
中,让
在第二次中,而不是其他任何地方。我想说的是,您需要在每次发送后/每次依赖它的测试之前清除交付。只有前两次依赖它,它们失败了。正如我前面提到的-您编写的第一个测试不是第一个运行的测试。您的示例是以随机顺序运行的,因此您首先编写的测试可能很容易成为最后一个运行的测试,这意味着其他测试已经发送了多封电子邮件。毕竟,如果第一个测试将在第二个测试之后运行呢?我给
let(:send1_email1){MyMailer.send1 a,b,c}
每个
description
只打一次电话,检查
MyMailer.deliveries.count
也打一次电话。我在每个描述中都清除了
MyMailer.deliveries.clear
套件已经发送了4封电子邮件,使您的测试失败了
-这是不可能的,因为它们被调用的次数正好是测试的2次-在第一次
中,让
在第二次中,而在其他任何地方都没有?after是指after:each?after:all和after有什么区别?之后意味着之后:每个?