0

J'ai donc une classe TimeBank, et elle est mise à jour, et obtient deux nouveaux attributs virtuels qui vont manipuler deux autres attributs existants (colonnes DB).Rails 4 Test Minitest Attributs virtuels

class TimeBank < ActiveRecord::Base 
    # validations, consts, few other methods omitted for brevity 

    def date_worked 
    @date_worked ||= self.start.to_date 
    rescue 
    Date.current 
    end 

    def date_worked=(date_worked_val) 
    self.attributes['date_worked'] = date_worked_val 
    end 

    def hours_worked 
    @hours_worked ||= hours 
    rescue NoMethodError 
    nil 
    end 

    def hours_worked=(hours_worked_val) 
    self.attributes['hours_worked'] = hours_worked_val 
    end 

    def hours 
    if attributes["hours"] 
     read_attribute(:hours).to_f 
    else 
     ((finish - start)/1.hour).to_f 
    end 
    rescue NoMethodError 
    0.0 
    end 

    # other methods omitted for brevity... 
end 

Tout fonctionne correctement lors de l'utilisation de l'application. Lors de l'exécution de tests, à chaque fois que j'instancie un TimeBank, j'obtiens uniquement les résultats des instructions rescue ci-dessus, à savoir, la date du jour pour date_worked et 0.0 pour hours_worked. Les setters semblent ne pas répondre, comme s'ils ne faisaient rien (pendant les tests).

J'avais aussi défini les setters à utiliser write_attribute(:date_worked, 'SOMEVAL') et tout cela fonctionne dans l'application, pour les tests, je reçois des erreurs comme

ActiveModel::MissingAttributeError: can't write unknown attribute hours_worked' 
app/models/time_bank.rb:110:in `hours_worked=' 

Un exemple d'un test serait la suivante:

describe "virtual attributes test" do 
    subject { TimeBank.new({member: @gus, admin_id: @addy.id, date_worked: Date.yesterday, hours_worked: 2.5, time_type: "store_shift", approved: true}) } 

    it "tests setter callbacks" do 
    subject.date_worked.must_equal Date.yesterday 
    subject.hours_worked.must_equal 2.5 
    end 
end 

Les deux assertions échouent toujours, puisqu'elles obtiennent la date du jour et 0.0 (les «valeurs par défaut» comme spécifié dans les getters). Si je place les attributs sur la ligne immédiatement avant les tests, cela n'a toujours aucun effet.

Je ne sais pas ce que je fais mal. Id aiment écrire des tests pour ces 2 attributs virtuels, mais n'importe quel arrangement de leurs valeurs semble n'avoir aucun effet. Je ne sais pas pourquoi cela ne fonctionne pas dans les tests, mais fonctionne bien dans l'application. Le même code fonctionne comme prévu dans les contrôleurs d'application. Quelqu'un peut-il m'aider à comprendre pourquoi?

Répondre

0

Le problème réside dans les méthodes de définition. Au lieu d'attribuer quelque chose à self.attributes["virtual_attribute"], une variable d'instance est nécessaire pour régler et retour, comme ceci:

def virtual_attribute=(virtual_attr_value) 
    @virtual_attribute = virtual_attr_value 
end 

Donc, pour mon exemple, je avais besoin:

def hours_worked=(hours_worked_val) 
    @hours_worked = hours_worked_val 
end 

deux l'application, et mon getter/setter tests dans minitest, se comporter comme prévu maintenant.