I am doing my testing with mocks and stubs but I can't get the desired output I want when testing the create
action in the controller.
The failing test:
describe 'authenticated user' do
let(:user) { instance_double(User) }
before do
allow(controller).to receive(:current_user) { user }
allow(controller).to receive(:authenticate_user!) { true }
end
describe "POST create" do
let(:achievement_params) { { title: "title" } }
let(:create_achievement) { instance_double(CreateAchievement) }
before do
allow(CreateAchievement).to receive(:new) { create_achievement }
end
it 'sends create message to CreateAchievement' do
expect(CreateAchievement).to receive(:new).with(achievement_params, user)
expect(create_achievement).to receive(:create)
post :create, achievement: achievement_params
end
end
end
The create
action in the controller
def create
service = CreateAchievement.new(params[:achievement], current_user)
service.create
render nothing: true
end
The error:
1) AchievementsController authenticated user POST create sends create message to CreateAchivement
Failure/Error: expect(CreateAchievement).to receive(:new).with(achievement_params, user)
#<CreateAchievement (class)> received :new with unexpected arguments
expected: ({:title=>"title"}, #<InstanceDouble(User) (anonymous)>)
got: (<ActionController::Parameters {"title"=>"title"} permitted: false>, #<InstanceDouble(User) (anonymous)>)
Diff:
@@ -1,2 +1,3 @@
-[{:title=>"title"}, #<InstanceDouble(User) (anonymous)>]
+[<ActionController::Parameters {"title"=>"title"} permitted: false>,
+ #<InstanceDouble(User) (anonymous)>]
that's because you need to "permit" your POST values, in your controller:
def achievement_params
params.require(:achievement).permit(:title)
end
and then, call it from your controller action:
service = CreateAchievement.new(achievement_params, current_user)
You need to permit the parameters in your controller:
private
def achievement_params
params.require(:achievement).permit(:title)
end
Change your create method to receive theses params, instead of params[:achievement]
:
def create
service = CreateAchievement.new(achievement_params, current_user)
service.create
render body: nil
end
And in your spec, you need to create the params using the ActionController::Parameters.new
method permitting the title
param:
let(:achievement_params) { ActionController::Parameters.new('title': 'title').permit(:title) }
Like the following:
describe 'POST create' do
let(:achievement_params) { ActionController::Parameters.new('title': 'title').permit(:title) }
let(:create_achievement) {instance_double(CreateAchievement)}
before do
allow(CreateAchievement).to receive(:new) {create_achievement}
end
it 'sends create message to CreateAchievement' do
expect(CreateAchievement).to receive(:new).with(achievement_params, user)
expect(create_achievement).to receive(:create)
post :create, params: {achievement: achievement_params }
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.