How can I use mock models in the specifications of an AuthLogic controller?

I am trying to write specifications for a controller without using instruments (using model models instead). This controller requires the user to log in to the system for which I use AuthLogic , following the recommendations of the author .

describe UsersController do def mock_user(stubs={}) @mock_user ||= mock_model(User, stubs) end context 'when logged in' do before { activate_authlogic } it "exposes the logged-in user as @user in response to GET (show)" do UserSession.create(mock_user) ... end ... end ... end 

All of these examples do not work on the UserSession.create(...) , reporting the effect:

 Mock 'User_1005' received unexpected message :changed? with (no args) 

I am not sure how to solve this; taunts with :changed? => false :changed? => false appropriate?

+4
source share
4 answers

Iain has published a solution for using layouts with AuthLogic . To rephrase, the following helpers are included in spec_helpers.rb :

 def current_user(stubs = {}) @current_user ||= mock_model(User, stubs) end def user_session(stubs = {}, user_stubs = {}) @current_user_session ||= mock_model(UserSession, {:user => current_user(user_stubs)}.merge(stubs)) end def login(session_stubs = {}, user_stubs = {}) UserSession.stub!(:find).and_return(user_session(session_stubs, user_stubs)) end def logout @user_session = nil end 

I have included this in my specifications and I find that it does exactly what I was hoping for. I have specifications of a working controller that explicate the model layout for login, so now they donโ€™t all break when I add a field to User. An example implementation of this in the specification is as follows:

 describe SecretsController do before { login } it "should be very very secret!" end 

PS I hate answering my question, but this is the answer I was looking for; I just did not find it early enough.

+6
source

Authlogic expects the entry to act as the active instance of the entry. You can use a real instance or layout, but if you use a layout / stub, you must be sure that it answers all the methods required by Authlogic.

I would suggest using a real active recording object instead of a layout. If you do not want to use the appliance, you can use Factory.

The final option should be to pass a layout that responds to any methods (you can easily accomplish this using the method_missing method). The problem with this solution is that you donโ€™t know in advance what value a particular method call should return.

Yes, you can pass false, but this is not a solution. This will require manually trying / adding a default value until you find a mock object that answers all Authlogic requests. But this will require you to constantly comply with authlogic for any internal changes in order to fix unanswered calls to your stub.

+1
source

In Rails 3, this bullying of UserSession no longer works, since AuthLogic UserSession is not an instance of ActiveRecord :: Base. Fix what works for me:

 class UserSession < Authlogic::Session::Base extend ActiveModel::Naming end 
+1
source

I found that mocking autologous objects were heavy, and I eventually abandoned the mockery. Instead, I now use the generator approach using object daddy . Now my functional tests are much happier. BTW, shoulda + object_daddy is absolutely rocky. In the case of transactional contexts, make sure my test database remains clean and I donโ€™t need to mock simple activerecord objects.

0
source

Source: https://habr.com/ru/post/1286554/


All Articles