web-dev-qa-db-fra.com

Comment tester les méthodes de classe dans RSPEC

J'ai écrit une méthode de classe simple Buy.get_days(string) et j'essaie de la tester avec différentes entrées de chaîne de texte. Cependant, je pense que c'est très prolixe.

  • Existe-t-il un moyen plus concis de tester les éléments suivants? 
  • Existe-t-il un Équivalent de subject pour méthodes que je peux simplement continuer à transmettre à Paramètres différents et vérifier les résultats? 
  • Existe-t-il un moyen d’éviter la description inutile à chaque it?

merci

 describe Buy do
   describe '.get_days' do
    it 'should get days' do
      Buy.get_days('Includes a 1-weeknight stay for up to 4 people')
      .should == 1
      end
    it 'should get days' do
      Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace')
      .should == 1
    end
    it 'should get days' do
      Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)')
      .should == 4
    end
  end
end
17
lulalala

Ceci est un moyen intéressant mais peut-être plus obtus d'utiliser le bloc 'sujet' avec les méthodes de classe.

Edit: Le lien link tel que rapporté par les archives de Wayback qui, je suppose, est sujet au même problème.

4
TCopple

Il n'y a pas d'équivalent subject pour appeler une méthode, utiliser it est donc le moyen d'aller ici. Le problème que je vois avec votre code tel que présenté est qu’il n’explique pas réellement ce que vous testez. Je voudrais écrire quelque chose de plus comme:

describe Buy do
  describe '.get_days' do
    it 'should detect hyphenated weeknights' do
      Buy.get_days('Includes a 1-weeknight stay for up to 4 people').should == 1
    end
    it 'should detect hyphenated nights' do
      Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace').should == 1
    end
    it 'should detect first number' do
      Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)').should == 4
    end
  end
end

J'émets des hypothèses sur ce que vous recherchez, mais j'espère que l'idée est claire. Cela conduira également à une sortie d'erreur beaucoup plus utile lorsqu'un test échouera. J'espère que cela t'aides!

13
Matt Sanders

Apparemment, il existe une méthode described_class.

https://www.relishapp.com/rspec/rspec-core/docs/metadata/describe-class

Je suppose que c'est plus propre que subject.class, car il n'introduit pas un autre appel de méthode ., ce qui réduit la lisibilité.

Utiliser described_class ou subject.class peut être plus DRY que de mentionner explicitement la classe dans chaque exemple. Mais personnellement, je pense que ne pas avoir la coloration syntaxique qui vient avec la mention explicite du nom de la classe est une sorte de déception, et je pense que cela réduit la lisibilité, malgré le fait que cela gagne totalement dans le département de maintenabilité.

Une question se pose concernant les meilleures pratiques:

Devez-vous utiliser classes_classes autant que possible à l'intérieur et à l'extérieur de la méthode .expect(), ou uniquement dans la méthode expect()?

11
ahnbizcad

Ceci peut être une vieille question mais vous pouvez toujours utiliser subject.class pour vous débrouiller:

describe Buy do
  describe '.get_days' do
    it { expect(subject.class.get_days('Includes a 1-weeknight stay for up to 4 people')).to eq 1 }
  end
end
6
Omar Ali

Une alternative à subject/it consiste à utiliser before/specify:

describe '#destroy' do
  context 'with children' do
    before { @parent = FactoryGirl.create(:parent, children: FactoryGirl.create_list(:child, 2) }
    specify { @parent.destroy.should be_false }
  end
end

Cela produira une description raisonnable dans le format de sortie -fd de RSpec:

#destroy
  with children
    should be false
0
bjnord