2 votes

Pourquoi mon test rspec double-t-il mes objets ?

Il s'agit d'un de ces cas où mon code fonctionne mais où mon test échoue et où j'ai besoin de savoir ce que je fais de mal ?

J'ai une classe Projet avec un all qui ne fait que produire des instances de cette classe :

class Project

    @@all_projects = []

    def initialize(options)
      @@all_projects << self
    end

    def self.all
    @@all_projects
  end
end

Maintenant Project.all fonctionne très bien mais la spécification que j'écris ne fonctionne pas.

context "manipulating projects" do
    before do
        options1 = {
            name: 'Building house'
        }

        options2 = {
            name: 'Getting a loan from the Bank'
        }

        @project1 = Project.new(options1)
        @project2 = Project.new(options2)
    end
        it "can print all projects" do
      Project.all.should eq([@project1, @project2])
    end

Le message d'échec que je reçois est le suivant :

Project manipulating projects can print all projects
     Failure/Error: Project.all.should eq([@project1, @project2])

       expected: [Building house, Getting a loan from the Bank]
            got: [Building house, Building house, Building house, Getting a loan from the Bank, Building house, Getting a loan from the Bank]

Voici les spécifications complètes dans un résumé : https://gist.github.com/4535863

Qu'est-ce que je fais de mal ? Comment puis-je le réparer ?

3voto

shioyama Points 15314

Il double les résultats parce qu'il exécute la before bloc pour chaque où l'attribut class est modifié (lors de l'initialisation de deux nouveaux projets), et (selon l'attribut Gist ) le test auquel vous faites référence est le second.

Pour éviter le problème, vous devrez réinitialiser @@all_projects dans un bloc arrière :

after do
  Project.class_variable_set :@@all_projects, []
end

Voir aussi : Comment effacer les variables de classe entre les tests rspec en ruby ?

(Merci à @ iain pour la suggestion de déplacer le code de réinitialisation vers une after plutôt qu'un bloc before bloc.)

1voto

iain Points 6208

Cela n'utilise pas before pour définir des variables d'instance puantes.

describe Project do
  let(:options1){ 
    {
      name: 'Building house',
      priority: 2,
      tasks: []
    }
  }
  let(:options2) {
    {
      name: 'Getting a loan from the Bank',
      priority: 3,
      tasks: []
    }
  }
  let(:project1) { Project.new(options1) }
  let(:project2) { Project.new(options2) }

  context "while starting up" do

    subject { Project.new options1 }
    its(:name) { should include('Building house') }

    its(:tasks) { should be_empty }
  end

  context "manipulating projects" do
    before :all do
      Project.all.clear
    end

    subject { Project.all }
    its(:count) { should be > 0 }

    it { should eq [project1, project2] }

  end

end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X