Ich habe eine einfache Klasse:Erwartet Lambdas in RSpec
class Maybe
def initialize(value, maybe_klass = Maybe)
@value = value
@maybe_klass = maybe_klass
end
attr_reader :value
def map(function)
return self if value.nil?
return maybe_klass.new(compose(value, function)) if value.is_a? Proc
maybe_klass.new(function.curry.call(*value))
end
private
attr_reader :maybe_klass
def compose(f, g)
lambda { |*args| f.call(g.call(*args)) }
end
end
Ich versuche es so zu testen:
it 'creates a new wrapped function that does both of the functions combined' do
maybe_double = double Maybe
add_four = ->(x) { x + 4 }
maybe = Maybe.new(add_four, maybe_double)
composed_lambda = ->(*args) { maybe.value.call(add_four.call(*args)) }
expect(maybe_double).to receive(:new).with(composed_lambda)
maybe.map(add_four)
end
Dieser Test nicht undefined method '+' for #<Proc:0x007fdd0b269e78>
Ich denke nicht Work- Das komponierte Lambda wird ausgewertet, bevor ich es brauche, aber ich bin mir nicht sicher. Was soll ich erwarten, dass die Methode initialize
des Doppels mit aufgerufen wird? Ist das überhaupt der richtige Weg, diese Klasse zu testen? Ich habe das Gefühl, dass ich die Interna der Klasse mit der composed_lambda
Variable zu sehr nachmache, aber ich bin mir nicht sicher, was ich stattdessen erwarten sollte.
Da die Funktion eine neue Instanz der Klasse, die wir testen, zurückgibt, ist es nicht wirklich möglich, diese ganze Klasse zu stubben - wir werden am Ende versuchen, das getestete System zu stubben.
Es sieht so aus, als würde ich 'receive (: new) {composed_lambda}' bekommen, wird der Block einfach ignoriert, also testet er nur, dass new aufgerufen wird. Was sich wie ein schwacher Test anfühlt, da es viele Wege gibt, die passieren könnten, ohne das Verhalten zu bekommen, nach dem ich suche – Adzz