2017-10-04 12 views
1

Je vais avoir cette méthode de classe sur mon modèle Post pour obtenir des archivesRspec - tableau archives pour correspondre ensemble testées

def self.archives 
    Post.unscoped.select("YEAR(created_at) AS year, MONTHNAME(created_at) AS month, COUNT(id) AS total") 
     .group("year, month, MONTH(created_at)") 
     .order("year DESC, MONTH(created_at) DESC") 
end 

C'est le test que je l'ai écrit pour ma méthode

context '.archives' do 

    first = FactoryGirl.create(:post, published_at: Time.zone.now) 
    second = FactoryGirl.create(:post, published_at: 1.month.ago) 

    it 'returns articles archived' do 
    archives = Post.archives() 

    expect(
     [{ 
     year: first.published_at.strftime("%Y"), 
     month: first.published_at.strftime("%B"), 
     published: 1 
     }, 
     { 
     year: second.published_at.strftime("%Y"), 
     month: second.published_at.strftime("%B"), 
     published: 1 
     }] 
    ).to match_array(archives) 
    end 
end 

Cependant Je reçois l'erreur suivante

expected collection contained: [#<Post id: nil>, #<Post id: nil>] 
actual collection contained: [{:year=>"2017", :month=>"October", :published=>1}, {:year=>"2017", :month=>"September", :total=>1}] 
the missing elements were:  [#<Post id: nil>, #<Post id: nil>] 
the extra elements were:  [{:year=>"2017", :month=>"October", :total=>1}, {:year=>"2017", :month=>"September", :total=>1}] 

Ainsi, bien que j'ai créé 2 usines, le tableau est archives vide. Qu'est-ce que je fais mal?

Répondre

1

norme Rspec est d'utiliser la syntaxe let pour définir des variables dans un contexte ou décrire bloc. Le test devrait ressembler à ceci:

describe '.archives' do 
    let!(:first) { FactoryGirl.create(:post, published_at: Time.zone.now) } 
    let!(:second) { FactoryGirl.create(:post, published_at: 1.month.ago) } 

    it 'returns year, month, and total for articles archived' do 
    actual_attributes = Post.archives.map { |post| [post.year, post.month, post.total] } 
    expected_total = 1 # I don't know why the query is returning 1 for total, but including this for completeness 
    expected_attributes = [first, second].map { |post| [post.created_at.year, post.created_at.strftime("%B"), expected_total] } 

    expect(actual_attributes).to match_array(expected_attributes) 
    end 
end 

Le problème ici est que vous comparez les enregistrements tirés avec seulement quelques attributs (le résultat de votre requête SQL) avec des enregistrements entièrement formés (créés par votre test). Ce test tire les attributs applicables des deux groupes et les compare.

+0

Cela ne semble pas fonctionner. Je reçois presque la même erreur – Lykos

+0

'collection attendue contenue: [# , # ] collection réelle contenue: [# ]' – Lykos

+0

J'ai l'a un peu modifié. Veuillez réessayer. – moveson

1

tableau réel est pas vide, il est un tableau de deux instances post avec ids unset (parce que Select dans la méthode .archives ne contient pas de champ id). Vous pouvez comparer les attendus hash pas archives, mais avec smth comme ça:

actual = Post.archives().map do |post| 
    { year: post["year"].to_s, month: post["month"], published: post["total"] } 
end 

expected = [{ 
    year: first.published_at.strftime("%Y").to_s, 
    month: first.published_at.strftime("%B"), 
    published: 1 
}, 
{ 
    year: second.published_at.strftime("%Y").to_s, 
    month: second.published_at.strftime("%B"), 
    published: 1 
}] 

expect(actual).to match_array(expected) 
+0

Je ne suis pas sûr de comprendre, vous voulez dire que cela devrait être à la place de mes attentes? – Lykos

+0

Clarifié la réponse. – hedgesky

+0

'collection attendue contenue: [{: année =>" 2017 ",: mois =>" Octobre ",: publié => 1}, {: année =>" 2017 ",: mois =>" Septembre ",: publié => 1}] collection actuelle contenue: [] les éléments manquants étaient: [{: year => "2017",: month => "October",: published => 1}, {: year => "2017", : month => "September",: published => 1}] ' – Lykos