使用TDD将索引循环变量传递给Ruby中的对象

时间:2017-09-06 16:46:14

标签: ruby loops rspec tdd test-coverage

我试图在TDD和Ruby中完成一组非常简单的测试。

我遇到的问题是尝试将一系列值从测试传递到被测对象。

代码的目的是猜测正确的秘密号码'通过向对象发送一系列猜测'通过for循环迭代地计算值,值在1到10的范围内。

测试应确认以下内容......

  1. 当猜测'值小于5(5是为'密码设置的固定值),对象应返回':less'的符号。

  2. 当猜测' value等于5,对象应返回':found_secret_number'的符号。

  3. 当猜测'如果value大于5,则对象应返回':more'的符号。

  4. 我发现虽然循环确实循环并生成所需的值,但循环只会为每个测试分配生成的最终循环值(该值为10)。我想测试会在循环中创建所有测试,然后在最后分配为lop变量设置的任何值(如果你快速查看它可能更有意义的代码......)。

    测试使用静态变量分配给对象,因此从功能角度看这个类是好的,但我不想要100%的线覆盖(例如'猜测'值为3 ,5和7),但希望100%的价值覆盖率(例如1,2,3,4,5,6,7,8,9和10)。

    我已播放并修改了代码但无法找到一种方法来分配我正在查找的值范围(1..10),而无需编写10个静态案例对于价值覆盖,那么有人建议如何在不使用十个静态情况的情况下做到这一点吗?:)

    我仍然在学习,所以如果你能尽可能简单地保持任何答案,那就会有所帮助;)同样,我解释这个问题可以帮助你理解它,任何有关我如何解释的反馈问题会更好,真的很感激;通讯,因为我确定你们都知道,非常重要,而且我也试图改善这一点。

    感谢:!)

    require 'rspec'
    
    class Game
    
      def initialize(secret_number)
        @secret_number = secret_number
      end
    
      def guess(number)
        if (number < @secret_number)
          :lower
        elsif
          (number > @secret_number)
          puts ("number is: " + number.to_s)
    
          :greater
        elsif (number == @secret_number)
          :found_secret_number
        end
      end
    end
    
    # 'describe' is a method, that is passed a 'Game' class,
    # it's not normally written like this but I've just shown it this
    # way, in this case, to affirm its just plain old Ruby.
    describe(Game) do
      subject { Game.new(5) }
      describe '#guess' do
        for i in 1..10
          if (i < 5)
            puts ("i is less than 5, it is: " + i.to_s)
            context 'when guessing a number that is lower than the secret number ' do
              it 'returns the symbol :lower' do
                expect(subject.guess(val)).to eq(:lower)
              end
            end
    
          elsif (i == 5)
            puts ("i is equal to 5, it is: " + i.to_s)
            context 'when guessing a number that is the SAME as the secret number ' do
              it 'returns the symbol :found_secret_number' do
                expect(subject.guess(val)).to eq(:found_secret_number)
              end
            end
    
          elsif (i > 5)
            puts ("i is greater than 5, it is: " + i.to_s)
            context 'when guessing a number that is higher than the secret number ' do
              it 'returns the symbol :greater' do
                expect(subject.guess(val)).to eq(:greater)
                end
             end
          end
        end
      end
    end
    

1 个答案:

答案 0 :(得分:1)

基本上所有花哨的测试方法,如describecontextit,都只是定义测试方法的方法。然后Rspec在实际运行测试时调用这些测试方法。因此,在这样的循环中调用它们并没有多大意义,因为您正在动态定义测试(在您的情况下肯定不需要它)。相反,您应该摆脱循环,并在这些测试用例中定义您的所有期望。例如:

describe(Game) do
  subject { Game.new(5) }
  describe '#guess' do
    context 'when guessing a number that is lower than the secret number ' do
      it 'returns the symbol :lower' do
        (1..4).each { |val| expect(subject.guess(val)).to eq(:lower) }
      end
    end

    context 'when guessing a number that is the SAME as the secret number ' do
      it 'returns the symbol :found_secret_number' do
        expect(subject.guess(5)).to eq(:found_secret_number)
      end
    end

    context 'when guessing a number that is higher than the secret number ' do
      it 'returns the symbol :greater' do
        (6..10).each { |val| expect(subject.guess(val)).to eq(:greater) }
     end
    end
  end
end

然后当我用rspec运行该文件时,我得到了

...

Finished in 0.02421 seconds (files took 0.26321 seconds to load)
3 examples, 0 failures