Come testare metodi privati in un ActiveRecord?


#1

Ciao sto provando a fare questo:

Model(monkey.rb):

class Monkey < ActiveRecord:Base

private
def secret; puts ‘shh’; end
end

Test(monkey_test.rb):

class Monkey
def public_secret; secret; end # creo un metodo public solo in test
per
poter testare il metodo privato
end

class MonkeyTest < Test::Unit::TestCase
def test_secret
assert_equal “shh”, Monkey.find(:first).public_secret
end
end

Il problema è che la riapertura dell’active record Monkey nella classe
di
test mi fa in qualche modo sparire le proprietà che ha originariamente
la
classe.
Lanciando il test mi becco: NoMethodError: undefined method
`primary_key’
for Monkey:Class.

togliendo la ridefinizione di Monkey nel test l’errore sparisce, ma
ovviamente non riesco a testare il metodo privato…
Qualcuno ha idee per un workaround?


#2

Paolo Donà ha scritto:

Qualcuno ha idee per un workaround?

Ti racconto un segreto che non tutti sanno :slight_smile:

class Monkey
private
def secret
puts “shhh!”
end
end

m = Monkey.new
m.secret
=> NoMethodError (private…)
m.send(:secret)
=> shhh

:slight_smile:


#3

On 6/5/07, Paolo Donà removed_email_address@domain.invalid wrote:

Ciao sto provando a fare questo:

togliendo la ridefinizione di Monkey nel test l’errore sparisce, ma
ovviamente non riesco a testare il metodo privato…
Qualcuno ha idee per un workaround?

il voler testare il metodo privato mi suggerisce che forse dovrebbe
essere
un metodo pubblico di una classe differente… magari qualcosa che sta in
lib. altrimenti inietta al volo nell’istanza il tuo “def public_secret”,
così è visibile anche da test il tuo intento di violare l’encapsulation.


#4

il voler testare il metodo privato mi suggerisce che forse dovrebbe essere
un metodo pubblico di una classe differente… magari qualcosa che sta in
lib.

Hai ragione ma non è il mio caso. Ho un active record che fa da proxy
ad
una tabella legacy attraverso una relazione belongs_to e voglio che il
metodo di relazione (es: Monkey#legacy) sia privato in modo che solo
Monkey
possa usarlo. Questo fa in modo che tutta la logica di interazione con
la
tabella legacy sia incapsulata in Monkey ed il resto dell’applicazione
se ne
frega. Non posso spostare il metodo di relazione in lib… e comunque è
anche difficile rendere privata una relazione.

altrimenti inietta al volo nell’istanza il tuo “def public_secret”,

così è visibile anche da test il tuo intento di violare l’encapsulation.

Si può fare ma è na palla perchè lo dovrei fare per ogni istanza che uso
nel
test… ovvero ogni volta che tiro su una fixture, non saprei come farlo
in
modo conciso.
Paolo


#5

yep thanks, quello in effetti fuziona…
ma la curiosità di sapere perchè si spacca è davvero troppa :slight_smile:
Paolo