Created
July 17, 2012 21:10
-
-
Save Sam-Serpoosh/3132125 to your computer and use it in GitHub Desktop.
a simple sign_in & sign_out machinery for an app I'm currently working on. I try to follow good OO design & separation of concerns, etc. & extract domain objects as much as possible & have fast-isolated tests. But can't stub simple methods of a module in
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SessionsHelper | |
include SignInOut | |
def create_cookie(user_id, user_salt); end | |
def remember_token; end | |
def delete_cookie; end | |
end | |
describe "Sign in and out" do | |
include SessionsHelper | |
it "signs the user in" do | |
user = stub(:id => stub) | |
user.stub(:salt => stub) | |
sign_in(user) | |
signed_in?.should be_true | |
end | |
... | |
#but as you can see this is so fragile and whenever I have a new method in SessionsHelper I have to define a stub one in the SessionsHelper in the spec | |
#also I can't express the expectations on its methods and stub some results for better live documentation style of specs and expressing stuff explicitly | |
#in my specs | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#This module will be included in SessionsHelper where cookies and remember_token stuff exists | |
module SignInOut | |
def sign_in(user) | |
create_cookie(user.id, user.salt) | |
@current_user = user | |
end | |
def current_user | |
@current_user || user_from_remember_token | |
end | |
def signed_in? | |
!@current_user.nil? | |
end | |
def sign_out | |
delete_cookie | |
@current_user = nil | |
end | |
def user_from_remember_token | |
AuthenticateUser.authenticate_with_salt(*remember_token) | |
end | |
end | |
module SessionsHelper | |
include SignInOut | |
def create_cookie(user_id, user_salt) | |
cookies.permanent.signed[:remember_token] = [user_id, user_salt] | |
end | |
def remember_token | |
cookies.signed[:remember_token] || [nil, nil] | |
end | |
def delete_cookie | |
cookies.delete(:remember_token) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SessionsHelper | |
include SignInOut #because it assumed cookies related methods will be in SessionsHelper it should be included in this for simulating the production code | |
end | |
describe "Sign in and out" do | |
include SessionsHelper | |
#I want to be able to stub some methods in SessionsHelper (or any module like this scenario) and express some call expectations like the following | |
it "creates the cookie and signs the user in" do | |
user = stub(:id => 1) | |
user.stub(:salt => "salt") | |
SessionsHelper.stub(:create_cookies).with(1, "salt") | |
sign_in(user) | |
signed_in?.should be_true | |
end | |
#And doing this kind of stubbing on the SessinosHelper methods like delete_cookie, remember_token, etc. (or methods of any other module like this scenario) | |
end |
Ouch, that double include is crazy :/
@steveklabnik I know it's not a good idea doing this. I finally figured it out how to do this. I can do something like the following for better and cleaner testing for this:
describe "Sign in and out" do
let(:sessions_helper) { stub.extend(SignInOut) }
it "creates cookie for the user" do
user_id, user_salt = 1, "salt"
user = stub(:id => user_id, :salt => user_salt)
sessions_helper.should_receive(:create_cookie).with(user_id, user_salt)
sessions_helper.sign_in(user)
end
....
end
this is a better and less confusing way. Thanks to @garybernhardt for the hint.
Thank you Steve for the review, I appreciate that ;)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Only self methods in a module can be stubbed out this way (like the last file spec example) but I need to stub out simple methods of a module like the create_cookie for instance in the SessionsHelper and I don't know how to do it!