RSpec - Hooks

在编写单元测试时,在测试之前和之后运行设置和拆卸代码通常很方便.设置代码是为测试配置或"设置"条件的代码.拆解代码执行清理,它确保环境在后续测试中处于一致状态.

一般来说,您的测试应该彼此独立.当您运行整个测试套件并且其中一个测试失败时,您希望确信它失败了,因为它正在测试的代码存在错误,而不是因为先前的测试使环境处于不一致状态.

RSpec中使用的最常见的钩子是钩子之前和之后.它们提供了一种定义和运行我们上面讨论的设置和拆除代码的方法.让我们考虑这个示例代码 :

class SimpleClass 
   attr_accessor :message 
   
   def initialize() 
      puts "\nCreating a new instance of the SimpleClass class" 
      @message = 'howdy' 
   end 
   
   def update_message(new_message) 
      @message = new_message 
   end 
end 

describe SimpleClass do 
   before(:each) do 
      @simple_class = SimpleClass.new 
   end 
   
   it 'should have an initial message' do 
      expect(@simple_class).to_not be_nil
      @simple_class.message = 'Something else. . .' 
   end 
   
   it 'should be able to change its message' do
      @simple_class.update_message('a new message')
      expect(@simple_class.message).to_not be 'howdy' 
   end
end

运行此代码时,您将获得以下输出和减号;

Creating a new instance of the SimpleClass class 
. 
Creating a new instance of the SimpleClass class 
. 
Finished in 0.003 seconds (files took 0.11401 seconds to load) 
2 examples, 0 failures

让我们仔细看看是什么发生. before(:each)方法是我们定义设置代码的地方.当您传递:each参数时,您指示before方法在示例组中的每个示例之前运行,即它在上面的代码中的describe块内部阻塞.

在line:@simple_class = SimpleClass.new,我们正在创建SimpleClass类的新实例,并将其分配给对象的实例变量.你可能想知道什么对象? RSpec在describe块的范围内创建一个特殊的类.这允许您为此类的实例变量赋值,您可以在示例中的块中访问它们.这也使得在我们的测试中编写更清晰的代码变得容易.如果每个测试(示例)都需要SimpleClass的实例,我们可以将该代码放在before钩子中,而不必将其添加到每个示例中.

请注意,"创建一个"SimpleClass类的新实例"被写入控制台两次,这表明,在每个它阻止中调用钩子之前.

正如我们所做的那样我们提到过,RSpec也有一个后挂钩,前后挂钩都可以:全部作为参数.后钩子将在指定目标之后运行. :all目标意味着钩子将在所有示例之前/之后运行.这是一个简单的例子,说明了何时调用每个钩子.

describe "Before and after hooks" do 
   before(:each) do 
      puts "Runs before each Example" 
   end 
   
   after(:each) do 
      puts "Runs after each Example" 
   end 
   
   before(:all) do 
      puts "Runs before all Examples" 
   end 
   
   after(:all) do 
      puts "Runs after all Examples"
   end 
   
   it 'is the first Example in this spec file' do 
      puts 'Running the first Example' 
   end 
   
   it 'is the second Example in this spec file' do 
      puts 'Running the second Example' 
   end 
end

当您运行上述代码时,您将看到此输出 :

Runs before all Examples 
Runs before each Example 
Running the first Example 
Runs after each Example 
.Runs before each Example 
Running the second Example 
Runs after each Example 
.Runs after all Examples