2013-07-09 2 views
0

У меня есть «обновленная запрашиваемая пользовательская часть» моего теста, которая терпит неудачу, и я не могу понять, почему.Ошибка математического ожидания ... Не понимаю, почему этот тест терпит неудачу (все отлично работает в браузере)

describe "PUT/PATCH #update_profile" do 

    context "with valid params" do 
     it "updates the requested user" do 
     user = create(:john_doe) 
     # Assuming there are no other users in the database, this 
     # specifies that the User created on the previous line 
     # receives the :update_attributes message with whatever params are 
     # submitted in the request. 
     User.any_instance.should_receive(:update_profile).with({identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}}) 
     put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}}} 

     end 

     it "assigns the requested user as @user" do 
     user = create(:john_doe) 
     put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}} } 
     expect(assigns(:user)).to eq(user) 
     end 

     it "redirects to the user" do 
     user = create(:john_doe) 
     put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}}} 

     expect(response).to redirect_to foundry_users_url 
     end 
    end 

2 других частей (правопреемников и перенаправлять) проходит нормально, и все работает, как ожидалось при тестировании в браузере.

Сообщение об ошибке "RSpec::Mocks::MockExpectationError: Exactly one instance should have received the following message(s) but didn't: update_profile"

EDIT: Я здесь добавить контроллер пользователей (я храню здесь только соответствующие части кода: создать действие обновления действия (для справки) и update_profile действие (которое вызывает спецификации потерпеть неудачу) . Помните, что только эта спецификация не удается, все другие работы, как ожидается, проблема только в том, как я написал тест.

пользователя has_one :identity и accepts_nested_attributes_for :identity

class Foundry::UsersController < ApplicationController 
    before_action :set_user, only: [:show, :edit, :update, :edit_profile, :update_profile, :destroy] 

def create 
    @user = User.new(user_params) 

    respond_to do |format| 
     if @user.save 
     format.html { redirect_to foundry_users_url, flash: {success: "User was successfully created."} } 
     format.json { render action: 'show', status: :created, location: @user } 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

def update 
    respond_to do |format| 
     if @user.update(user_params_for_update) 
     format.html { redirect_to foundry_users_url, notice: 'Credentials were successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit' } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

def update_profile 
    respond_to do |format| 
     if @user.update(user_params_for_update_profile) 

     format.html { redirect_to foundry_users_url, notice: 'Profile was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit_profile' } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

def user_params 
    # used only on creation 
    params.require(:user).permit(:email, identity_attributes: [:last_name, :first_name]) 
    end 

    def user_params_for_update 
    # used only on 'regular' update action -- updates only credentials that are user's attributes 
    params.require(:user).permit(:email, :password, :password_confirmation) 
    end 

    def user_params_for_update_profile 
    # used only on update_profile action (later should have identity_attributes, addresses_attributes, and some others...) 
    params.require(:user).permit(identity_attributes: [:last_name, :first_name, :email_rescue, :dob, :bio, :gender, :id]) 
    end 

Я полагаю, что я делаю что-то wromg где-то, но я не могу увидеть, где и почему ...

Спасибо за вашу помощь

+0

Что произойдет, если вы удалите '.with (...' часть из строки, начиная с 'User. any_instan ce.'? – DNNX

+0

такая же вещь – phron

+0

Не могли бы вы показать метод контроллера? – DNNX

ответ

1

Я его на работу! Спасибо @DNNX, который ставит меня в правильном направлении, проблема, как и ожидалось, в том, как я написал тест, user.any_instance должен получать: update_profile вместо обновления. Я ставлю здесь прохождение спецификации для информации ..

describe "PUT/PATCH #update_profile" do 
    context "with valid params" do 
     it "updates the requested user" do 
     user = create(:john_doe) 
     User.any_instance.should_receive(:update_profile).with({"identity_attributes"=>{"last_name" => "BIDON", "first_name" => "Bidon", "dob" => "1970-07-15"}}) 

     put :update_profile, {:id => user.to_param, :user => {:identity_attributes =>{last_name: 'BIDON', first_name: 'Bidon', dob: "1970-07-15"}}} 
     end 

     it "assigns the user as @user" do 
     user = create(:john_doe) 
     # Trigger the behavior that occurs when valid params are submitted 
     User.any_instance.stub(:update_profile).and_return(true) 
     put :update_profile, {:id => user.to_param, :user => { identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15"}}} 
     expect(assigns(:user)).to eq(user) 
     end 

     it "redirects to users list" do 
     user = create(:john_doe) 
     # Trigger the behavior that occurs when valid params are submitted 
     User.any_instance.stub(:update_profile).and_return(true) 
     put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15"}}} 
     expect(response).to redirect_to foundry_users_url 
     end 

    end 

    context "with invalid params" do 
     it "assigns the user as @user" do 
     user = create(:john_doe) 
     # Trigger the behavior that occurs when invalid params are submitted 
     User.any_instance.stub(:update_profile).and_return(false) 
     put :update_profile, {:id => user.to_param, :user => { identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id" => user.identity.id}}} 
     expect(assigns(:user)).to eq(user) 
     end 

     it "re-renders the 'edit_profile' template" do 
     user = create(:john_doe) 
     # Trigger the behavior that occurs when invalid params are submitted 
     User.any_instance.stub(:update_profile).and_return(false) 
     put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id" => user.identity.id}}} 
     expect(response).to render_template :edit_profile 
     end 
    end 
    end 

остальной код отвечал на мой вопрос все тот же .. и теперь все тесты зеленый

EDIT как сказал, чтобы DNNX в комментариях Я забыл упомянуть о существенной MODIF к контроллеру себя, я положил его здесь:

def update_profile 
    respond_to do |format| 
     if @user.update_profile(user_params_for_update_profile) // changed to call update_profile instead of update ! 
     // rest of code still the same 

Приветствия

+0

Проходят ли тесты, если вы удаляете 'User.any_instance.stub (: update_profile) .and_return (false)'? Модель 'User' имеет метод с именем' update_profile'? Я не думаю, что этот тест правильный. 'stub' не делает ничего полезного в этом тесте - результат будет таким же, если вы удалите строки, начинающиеся с' User.any_instance'. – DNNX

+0

Я тоже обновил контроллер, просто забыл упомянуть об этом! Я обновляю код контроллера в решении – phron

+0

@DNNX - см. Мой комментарий к прецеденту. Я забыл изменения в контроллере в response_to, если это «@ user.update_profile» ... Я обновляю решение этой частью – phron

0

Ваш контроллер не вызывает update_profile на любом экземпляре User. Он называет User#update. Попробуйте это:

User. 
    any_instance. 
    should_receive(:update). 
    with(identity_attributes: { 
     "last_name" => "Bidon", 
     "first_name" => "Bidon", 
     "dob" => "1970-07-15", 
     "id" => user.identity.id}) 

Или это, если приведенный выше код не работает:

User.any_instance.should_receive(:update) 
+0

, заставив меня в правильном направлении. Я отправил полный ответ с правильным кодом, чтобы уточнить ... – phron