2016-05-05 7 views
3

ich eine private Methode in einem ControllerRails Test Controller private Methode mit params

private 
    def body_builder 
    review_queue = ReviewQueueApplication.where(id: params[:review_queue_id]).first 
    ... 
    ... 
    end 

Ich möchte gerade testen Sie die body_builder Methode haben, ist es ein Verfahren buidling die Nutzlast für einen Rest api-Anruf-Client. Es benötigt jedoch Zugang zu den Params.

describe ReviewQueueApplicationsController, type: :controller do 
    describe "when calling the post_review action" do 
    it "should have the correct payload setup" do 
     @review_queue_application = ReviewQueueApplication.create!(application_id: 1) 
     params = ActionController::Parameters.new({ review_queue_id: @review_queue_application.id }) 
     expect(controller.send(:body_builder)).to eq(nil) 
    end 
    end 
end 

Wenn ich laufen die oben es wird die body_builder Methode senden, aber dann wird es brechen, weil die params nicht korrekt eingerichtet worden, da sie in einem Aufruf der Aktion sein würde.

Ich konnte immer einen bedingten Parameter für die body_builder Methode erstellen, so dass es entweder ein Argument nimmt, oder es wird die params wie diese def body_builder(review_queue_id = params[:review_queue_id]) und dann im Test controller.send(:body_builder, params), aber ich fühle mich verwenden, dass eine Änderung des Codes der Testdurchlauf zu machen ist falsch, es sollte es einfach so testen wie es ist.

Wie kann ich Params in den Controller bekommen, bevor ich die private Methode dazu sende?

+0

Mein Vorschlag wäre, tatsächlich den RESTful Einstiegspunkt mit den richtigen Parametern aufzurufen. Wenn Sie ein Verhalten haben, das auftreten muss, bevor Ihre body_builder-Methode aufgerufen werden kann, können Sie die Ausführung über den richtigen Pfad nachahmen und stubben. Dann setzen Sie eine Erwartung auf die controller.body_builder-Methode, anstatt sie nur aufzurufen. Ich weiß, das ist schwerer als nur die private Methode aufrufen, aber ich habe immer gefühlt, dass, wenn man private private Methoden direkt in Tests aufruft, du aus der Test- "Sandbox" für dieses Objekt heraustrittst. – jaydel

+0

@jaydel, ich bekomme völlig, woher du kommst, das einzige Problem ist das Testen des eigentlichen Aufrufs zum Einstiegspunkt ist, dass es die 'RestClient :: Request'-Aktion auslöst, die bereits getestet wurde, das möchte ich voraussetzen Dieser Teil funktioniert zwar korrekt, aber die Erstellung der Nutzlast wird vernachlässigt, wenn wir der Nutzlast Dinge hinzufügen, von denen sie nicht erwartet, dass sie fehlschlagen. – TheLegend

+1

Ja, ich verstehe Ihre Bedenken. Ich bin mit den Details dieses speziellen Verhaltens nicht vertraut, aber ist es möglich, diesen Teil zu verspotten und zu stümpfen, um die Nutzlast so aufzubauen, wie Sie es testen möchten. Ich bin jedoch außerhalb des Kontextes gewandert, den ich verstehe, und das weißt du natürlich viel besser als ich. also nur zum Nachdenken – jaydel

Antwort

2

Ich denke, Sie sollten

params = ActionController::Parameters.new({ review_queue_id: @review_queue_application.id }) 

mit

controller.params = ActionController::Parameters.new({ review_queue_id: @review_queue_application.id }) 

und Sie sollten gut ersetzen können. Die Parameter sind nur ein Attribut des Controllers (das tatsächliche Attribut ist @_params, aber es gibt Methoden für den Zugriff auf diesen ivar. Versuchen Sie controller.inspect in einer Ansicht).

+0

Übrigens, nachdem Sie dies gesagt haben, sollten Sie natürlich keine privaten Methoden testen ;-) – niels

+1

sollten sie nicht direkt *** *** testen, vielleicht? Wenn sie kompliziert sind und eine Logik haben, die schief gehen kann, sollten sie meiner Meinung nach getestet werden. – jaydel

+0

Ich habe eine kleine Politik, die ist, wenn ich eine Ausnahme bekomme: Ich beginne sofort den Prozess, indem ich einen Test schreibe. Auf diese Weise weiß ich, dass ich nie eine Ausnahme bekommen werde, die meisten meiner privaten Methoden tragen schwere IP-Anforderungen und brechen ziemlich viel. Auch wenn es schmutzig erscheint, wenn man diese Methoden abschickt, denke ich, wenn es wirklich schwierig ist, private Methoden zu testen, dann stimmt etwas nicht mit der Klasse, die ich schreibe. – TheLegend