2012-12-19 5 views
0

생성시 ActiveMerchant로 지불 처리와 관련된 예약 모델 생성을 테스트하려고합니다.Rspec factory_girl ActiveMerchant 정의되지 않은 메소드`credit_card = '

ActiveMerchant Railscasts에 이어 지불 처리를위한 초기 설정. 결제가 앱에서 정상적으로 작동합니다. "valid_credit_card"나는 Reservation 공장 내에서 그리고 그 자체 내에서 credit_card 객체 생성 시도했습니다 (http://railscasts.com/episodes/145-integrating-active-merchant)

기본 테스트

그냥 예약을 확인하려고 공장은 ... 만들 수 있습니다. 테스트 결과 : reservation_sets

Factory.define :reservation do |f| 
    f.association :user 
    f.rooms { |a| [a.association(:room)] } 
    f.arrival Time.now + 2.weeks 
    f.nights 2 
    f.phone "555-123-1234" 
    f.credit_card :valid_credit_card 
end 

Factory.define :valid_credit_card, :class => ActiveMerchant::Billing::CreditCard do |f| 
    expiration_date = Time.zone.now + 1.year 
    f.type "visa" 
    f.number "4111111111111111" 
    f.verification_value "333" 
    f.month expiration_date.strftime("%m") 
    f.year expiration_date.strftime("%y") 
    f.first_name "Bob" 
    f.last_name "Smith" 
end 

그리고 사양/모델/reservation_spec.rb을 통해 사용자와 has_many 객실 belongs_to

1) Reservation should have a valid factory 
Failure/Error: @current_reservation = Factory.create(:reservation) 
NoMethodError: 
undefined method `credit_card=' for #<Reservation:0xb5f6173c> 
# ./spec/models/reservation_spec.rb:11 

예약. @credit_card Factory.build를 사용하면 credit_card를 "저장"하는 데 오류가 발생합니다.

나는 라인 f.credit_card을 제거하는 경우 : valid_credit_card 나는 :monthattr_accessor에 나열된 경우에도 :month 에 대한 NoMethodError를 얻을. 앱 내에서 예약 생성이 작동합니다.

1) Reservation should have a valid factory 
    Failure/Error: @current_reservation = Factory.create(:reservation) 
    NoMethodError: 
     undefined method `month' for nil:NilClass 

describe Reservation do 
    before :each do 
    @smith = Factory.create(:user) 
    @room = Factory.create(:room) 
    #@credit_card = Factory.build(:valid_credit_card) 
    end 
    it "should have a valid factory" do 
    @current_reservation = Factory.create(:reservation) 
    @current_reservation.should be_valid 
    end 
end 

내가 간과하고있는 내용은 무엇입니까? ...?

예약 모델 발췌

class Reservation < ActiveRecord::Base 
    # relationships 
    belongs_to :user 
    has_many :reservation_sets, 
     :dependent => :destroy 
    has_many :rooms, 
      :through => :reservation_sets 
    has_many :transactions, 
      :class_name => 'ReservationTransaction', 
      :dependent => :destroy 

    attr_accessor :card_number, :card_verification, :card_expires_on, :card_type, :ip_address, :rtype, :month, :year 
    # other standard validations 
    validate :validate_card, :on => :create 

    # other reservation methods... 
    # gets paid upon reservation creation 
    def pay_deposit 
    # Generate active merchant object 

    ReservationTransaction.gateway = 
     ActiveMerchant::Billing::AuthorizeNetGateway.new({ 
     :login => rooms[0].user.gateway_login, 
     :password => rooms[0].user.gateway_password 
     }) 

    response = ReservationTransaction.gateway.purchase(deposit_price_in_cents, credit_card, purchase_options) 
    t = transactions.create!(:action => "purchase", :amount => deposit_price_in_cents, :response => response) 
    if response.success? 
     update_attribute(:reserved_at, Time.now) 
     # update state 
     payment_captured! 
    else 
     transaction_declined! 
     errors.add :base, response.message 
    end 
    t.card_number = credit_card.display_number 
    t.save! 
    response.success? 
    end 

    def validate_card 
    unless credit_card.valid? 
     credit_card.errors.full_messages.each do |message| 
     errors.add :base, message #_to_base message 
     end 
    end 
    end 

    def credit_card 
    @credit_card ||= ActiveMerchant::Billing::CreditCard.new(
     :type    => card_type, 
     :number    => card_number, 
     :verification_value => card_verification, 
     :month    => card_expires_on.month, 
     :year    => card_expires_on.year, 
     :first_name   => first_name, 
     :last_name   => last_name 
    ) 
    end 

그리고 예약 컨트롤러는 credit_card 값을 지정하려고하는 것 같습니다

def create 
    @reservation = Reservation.new(params[:reservation]) 
    @reservation.arrival = session[:arrival] 
    @reservation.nights = session[:nights] 
    @reservation.number_kids = session[:number_kids] 
    @reservation.number_adults = session[:number_adults] 
    session[:creating_reservation] = 1 
    @reservation.user_id = @reservation.rooms[0].user_id 
    session[:owner] = @reservation.user_id 
    @rooms = Room.all 
    @reservation.ip_address = request.remote_ip   

    # get room owner... 
    @owner = User.find(@reservation.user_id) 
    respond_to do |format| 
     if @reservation.save 
     if @reservation.pay_deposit 
      #set cc... 
      @reservation.transactions[0].card_number = @reservation.send(:credit_card).display_number 
      ReservationMailer.reservation_created(@reservation).deliver 
      ReservationMailer.reservation_notice(@reservation).deliver 
      session[:arrival] = nil 
      session[:reservation_id] = @reservation.id 
      if @owner 
      thanks_path = "#{@owner.permalink}/reservations/#{@reservation.id}" 
      else 
      thanks_path = @reservation 
      end 
      format.html { redirect_to @reservation, :notice => 'Reservation was successfully created.' } 
      format.json { render :json => @reservation, :status => :created, :location => @reservation } 
      # also trigger email sending or wherever that is 
      # receipt email and order notification 
      # 
     else 
      # set flash or show message problem w/ transaction 

      format.html { render :action => "new" } 
     end 
     else 
     format.html { render :action => "new" } 
     format.json { render :json => @reservation.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 
+0

'예약'모델은 어떻게 생겼습니까? – Joe

+0

'예약'모델 및 생성 작업의 일부를 추가했습니다. 이 중 일부는 리팩토링해야한다는 것을 알고 있습니다 ... 아마도 문제의 일부입니다 ... 확인해 주셔서 감사합니다. – b2tech

답변

0

에서 활동 만들기,하지만 당신은 정말 class accessor이없는 . 그래서 어디 전화를하려고 f.credit_card :valid_credit_card 작동하지 않습니다.

mock_cc = ActiveMerchant::Billing::CreditCard.new(
     :type    => card_type, 
     :number    => card_number, 
     :verification_value => card_verification, 
     :month    => card_expires_on.month, 
     :year    => card_expires_on.year, 
     :first_name   => first_name, 
     :last_name   => last_name 
    ) 

Reservation.stub(:credit_card).and_return(mock_cc) 

이이 모델이 credit_card이라고 때 그래서 것 만들 것 :

나는 당신의 공장에서 f.credit_card :valid_credit_card를 제거하고 rspec stubs을 사용으로 보일 것이다, 당신은 당신의 RSpec에 시험에서 다음과 같이 뭔가를 할 수 조롱 된 객체를 반환합니다.

+0

고마워, 이것이 나를 올바른 방향으로 인도하는 데 도움이되었다. 'attr : credit_card' 라인을 추가하는 것 외에도'f.card_expires_on'을 설정해야 할 때'f.month'와'f.year'를 설정하려고했습니다. 시험 합격. – b2tech

관련 문제