ruby-on-rails - tutorial - rspec model



Comment RSpec s'attend à travailler dans ROR (2)

Voici un extrait de Ryan Bates Railscast sur demande Specs et Capybara

require 'spec_helper'  

describe "Tasks" do  
  describe "GET /tasks" do  
    it "displays tasks" do  
      Task.create!(:name => "paint fence")  
      visit tasks_path  
      page.should have_content("paint fence")  
    end  
  end  

  describe "POST /tasks" do  
    it "creates a task" do  
      visit tasks_path  
      fill_in "Name", :with => "mow lawn"  
      click_button "Add"  
      page.should have_content("Successfully added task.")  
      page.should have_content("mow lawn")  
    end  
  end  
end  

Et voici un extrait des docs sur RSPec Expectations

describe Counter, "#increment" do
  it "should increment the count" do
    expect{Counter.increment}.to change{Counter.count}.from(0).to(1)
  end

  # deliberate failure
  it "should increment the count by 2" do
    expect{Counter.increment}.to change{Counter.count}.by(2)
  end
end

Donc, fondamentalement, le

expect { click_button "Create my account" }.not_to change(User, :count)

fait partie RSpec:

expect {...}.not_to change(User, :count)

et partie Capybara

click_button "Create my account"

(Voici un lien vers le DSL de Capyabara - vous pouvez rechercher click_button )

On dirait que vous cherchez un exemple global avec les deux. Ce n'est pas un exemple parfait, mais cela pourrait ressembler à ceci:

describe "Tasks" do  
  describe "GET /tasks" do  
    it "displays tasks" do  
      expect { click_button "Create my account" }.not_to change(User, :count)
    end  
  end 
end 

https://ffff65535.com

En passant par Ruby On Rails Tutorial de Michael Hartl, dans la section où l'auteur écrit test d'intégration pour valider sa page d'inscription, il a utilisé le code spinet ci-dessous. J'ai eu ce que le code fait, mais je ne pouvais pas comprendre le «comment», c'est-à-dire ne pas comprendre l'ordre d'exécution.

expect { click_button "Create my account" }.not_to change(User, :count)

Quelqu'un peut-il expliquer la sémantique de la chaîne de méthodes et de blocs ci-dessus et comment ils s'emboîtent?


Vous utiliseriez expect ... change pour vérifier qu'un appel de méthode particulier change - ou ne change pas - d'une autre valeur. Dans ce cas:

expect { click_button "Create my account" }.not_to change(User, :count)

entraînera rspec à faire ce qui suit:

  1. Exécutez User.count et notez la valeur renvoyée. (Ceci peut être spécifié comme un récepteur et un nom de méthode, comme (User, :count) { User.count } (User, :count) dans votre exemple, ou comme un bloc arbitraire de code, comme { User.count } .
  2. Exécutez click_button "Create my account" qui est une méthode Capybara qui simule un clic de souris sur un lien.
  3. Exécutez User.count nouveau.
  4. Comparez les résultats de # 1 et # 3. Si elles diffèrent, l'exemple échoue. Si ce sont les mêmes, ça passe.

D'autres façons d'utiliser expect ... change :

expect { thing.destroy }.to change(Thing, :count).from(1).to(0)
expect { thing.tax = 5 }.to change { thing.total_price }.by(5)
expect { thing.save! }.to raise_error
expect { thing.symbolize_name }.to change { thing.name }.from(String).to(Symbol)

Certains docs sont ici .

Comment cela se passe est un peu mystérieux, et il n'est pas du tout nécessaire de comprendre comment cela fonctionne pour l'utiliser. Un appel à expect consiste à définir une structure à exécuter par rspec, en utilisant le propre DSL personnalisé de rspec et le système de "matchers". Gary Bernhardt a un screencast plutôt net dans lequel il soutient que le mystère de rspec tombe naturellement d'un langage dynamique comme le rubis. Ce n'est pas une bonne introduction à l' utilisation de rspec, mais si vous êtes curieux de savoir comment tout cela fonctionne, vous pourriez trouver cela intéressant.

METTRE À JOUR

Après avoir vu votre commentaire sur une autre réponse, je vais ajouter quelques mots sur l'ordre des opérations. L'astuce non intuitive est que c'est le matcher ( change dans ce cas) qui exécute tous les blocs. expect a un lambda, not_to est un alias pour should_not dont le travail est de passer le lambda sur le matcher. Le matcher dans ce cas est un change qui sait exécuter son propre argument une fois, puis exécuter le lambda qui lui a été passé (celui d' expect ), puis réexécuter son propre argument pour voir si les choses ont changé. C'est difficile parce que la ligne semble devoir s'exécuter de gauche à droite, mais comme la plupart des pièces ne font que passer des blocs de code, elles peuvent les mélanger dans l'ordre qui convient le mieux au matcher.

Je ne suis pas un expert sur les internes rspec, mais c'est ma compréhension de l'idée de base.





capybara