Как я могу проверить, что мой обратный вызов before_save делает правильно - PullRequest
3 голосов
/ 12 апреля 2011

У меня есть обратный вызов на моей модели ActiveRecord, как показано ниже:

  before_save :sync_to_external_apis

  def sync_to_external_apis                                                                                                 
    [user, assoc_user].each {|cuser|
      if cuser.google_refresh
        display_user = other_user(cuser.id)
        api = Google.new(:user => cuser)
        contact = api.sync_user(display_user)
      end
    }
  end

Я хотел бы написать тест rspec, который проверяет этот вызов save! в экземпляре этой модели вызывает sync_user для нового экземпляра Google, когда google_refresh имеет значение true. Как я мог это сделать?

Ответы [ 3 ]

4 голосов
/ 12 апреля 2011
it "should sync to external apis on save!" do
  model = Model.new
  model.expects(:sync_to_external_apis)
  model.save!
end

Кстати, запрашивать ненадежные ресурсы, такие как Интернет, во время цикла запрос-ответ - плохая идея.Вместо этого я бы предложил создать фоновую работу.

0 голосов
/ 17 апреля 2011

Мокко это путь. Я не знаком с rspec, но вот как бы вы это делали в тестовом модуле:

def test_google_api_gets_called_for_user_and_accoc_user
    user = mock('User')                  # define a mock object and label it 'User'
    accoc_user = mock('AssocUser')       # define a mock object and label it 'AssocUser'

    # instantiate the model you're testing with the mock objects
    model = Model.new(user, assoc_user)

    # stub out the other_user method.  It will return cuser1 when the mock user is 
    # passed in and cuser2 when the mock assoc_user is passed in
    cuser1 = mock('Cuser1')
    cuser2 = mock('Cuser2')
    model.expects(:other_user).with(user).returns(cuser1)
    model.expects(:other_user).with(assoc_user).returns(cuser2)


    # set the expectations on the Google API
    api1 - mock('GoogleApiUser1')          # define a mock object and lable it 'GoogleApiUser1'
    api2 - mock('GoogleApiUser2')          # define a mock object and lable it 'GoogleApiUser2'

    # call new on Google passing in the mock  user and getting a mock Google api object back
    Google.expects(:new).with(:user => cuser1).returns(api1)
    api1.expects(:sync_user).with(cuser1)

    Google.expects(:new).with(:user => cuser2).returns(api2)
    api2.expects(:sync_user).with(cuser2)

    # now execute the code which should satisfy all the expectations above
    model.save!
end

Выше может показаться сложным, но это не один раз, когда вы освоите его. Вы проверяете, что когда вы вызываете save, ваша модель делает то, что должна, но у вас нет лишних хлопот или затрат времени на общение с API, создание записей базы данных и т. Д.

0 голосов
/ 12 апреля 2011

Обычный метод тестирования - убедиться, что результаты соответствуют ожидаемым.Поскольку в этом случае вы используете API, это может усложнить ситуацию.Вы можете обнаружить, что использование mocha для создания фиктивного объекта, который вы можете отправлять вызовами API, позволит вам заменить класс Google чем-то, что работает так же хорошо для целей тестирования.

Aболее простой, но более грубый подход - использовать переключатель «тестового режима»:

def sync_to_external_apis
  [ user, assoc_user ].each do |cuser|
    if (Rails.env.test?)
      @synced_users ||= [ ]
      @synced_users << cuser
    else
      # ...
    end
  end
end

def did_sync_user?(cuser)
  @synced_users and @synced_users.include?(cuser)
end

Это простой подход, но он не подтвердит правильность ваших вызовов API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...