RSpe c - как исправить - ArguementError: неверное количество аргументов (задано 0, ожидается 1) - Ruby - PullRequest
0 голосов
/ 23 февраля 2020

Я новичок в изучении RSpe c. Кажется, я не понимаю, почему мой тест #start method не проходит.

был бы признателен, если бы мне могли объяснить.

ошибка, которую я получаю:

CardGame
  attributes
    should have a name
  #response method
    should say hello
  #start method
    can only implement class methods that are defined on a class (FAILED - 1)

Failures:

  1) CardGame#start method can only implement class methods that are defined on a class
     Failure/Error:
       def initialize(name)
         @name = name
       end

     ArgumentError:
       wrong number of arguments (given 0, expected 1)
     # ./lib/CardGame.rb:4:in `initialize'
     # ./spec/class_double_spec.rb:29:in `block (3 levels) in <top (required)>'

Finished in 0.01178 seconds (files took 0.30252 seconds to load)
3 examples, 1 failure

Failed examples:

rspec ./spec/class_double_spec.rb:27 # CardGame#start method can only implement class methods that are defined on a class

➜  rspec-course 

class_double_spe c .rb

[ruby/spec/class_double_spec.rb]

    require 'spec_helper'
    require 'pry'
    require './lib/CardGame'
    require './lib/Deck'

    describe CardGame do
      let(:card) { instance_double(CardGame, 
                                  name: 'poker',
                                  response: 'hello')} 
      let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }

      context 'attributes' do
        it 'should have a name' do
          expect(card.name).to eq('poker')
        end
      end

      context '#response method' do
        it 'should say hello' do
          allow(card).to receive(:response).and_return('hello')
          expect(card.response).to eq('hello')
        end
      end

      context '#start method' do
        it 'can only implement class methods that are defined on a class' do
          expect(deck_klass).to receive(:build)
          card.start
          expect(card.cards).to eq(['Ace', 'Queen'])
        end
      end
    end 

CardGame.rb

[ruby/lib/CardGame.rb]

    class CardGame
      attr_accessor :name, :cards

      def initialize(name)
        @name = name
      end

      def response
        'hello'
      end

      def start
        @cards = Deck.build
      end
    end

Палуба. Rb

[ruby/lib/Deck.rb]

    class Deck
      def self.build
        # business logic to build cards
      end
    end

1 Ответ

1 голос
/ 24 февраля 2020

Вы издеваетесь над издевательством. Одно из правил, которое следует строго соблюдать, - не издеваться над тестируемым устройством, поэтому вместо

describe CardGame do
      let(:card) { instance_double(CardGame, 
                                  name: 'poker',
                                  response: 'hello')} 
      let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }

      context 'attributes' do
        it 'should have a name' do
          expect(card.name).to eq('poker')
        end
      end
end

сделайте это

describe CardGame do
      let(:card) { CardGame.new(name) }
      let(:name) { 'poker'}

      context 'attributes' do
        it 'should have a name' do
          expect(card.name).to eq('poker')
        end
      end
end

Почему бы вам не высмеять тестируемое устройство?

      context '#response method' do
        it 'should say hello' do
          allow(card).to receive(:response).and_return('hello')
          expect(card.response).to eq('hello')
        end
      end

Потому что в этом примере вы только тестируете, что фреймворк RSpe c работает. Упростите его

      context '#response method' do
        it 'should say hello' do
          expect(card.response).to eq('hello')
        end
      end

Последний пример:

      context '#start method' do
        it 'can only implement class methods that are defined on a class' do
          expect(deck_klass).to receive(:build)
          card.start
          expect(card.cards).to eq(['Ace', 'Queen'])
        end
      end

Выглядит лучше, проверенный класс не тестируется напрямую, а используется тестируемым модулем (Card).

Если вы изучаете RSpe c - постарайтесь высмеивать как можно меньше. Это заставит вас создавать свои классы, чтобы их было легко тестировать. Прямо сейчас вы разрабатываете его в своем старом привычном стиле, что делает класс трудным для тестирования, что вынуждает вас использовать насмешки (и поскольку вы только учитесь - легко не заметить место c, где вас нет ничего не проверяю)

...