Search code examples
rubyunit-testingrspecnomethoderror

Rspec "NoMethodError"


I'm new to Unit Testing in Ruby using RSpec and I'm having trouble performing a very basic Unit test. I'm used to unit testing in Python and JavaScript, and I usually don't run into this problem.

I'm simply trying to test a STDOUT using the puts statement. Here is my spec.

my_spec.rb

require 'my_file'

  describe C do
    before(:all) do
      @c = C.new
    end

    describe C do
      subject(:C) { described_class.new }
      it 'should print Hello World' do
        expect {@c.main}.to output("Hello world").to_stdout
      end
    end
  end

Here is my_file.rb

class C
    def main
        puts "Hello World"
    end
end

No major code here, just a simple test for Output, but I'm receiving the an NoMethodError error when I run my spec:

Failures:

  1) C C should print Hello World
     Failure/Error: expect {@c.main}.to output("Hello world").to_stdout

     NoMethodError:
       undefined method `main' for #<C:0x007fe54488a550>
     # ./spec/my_spec.rb:12:in `block (4 levels) in <top (required)>'
     # ./spec/my_spec.rb:12:in `block (3 levels) in <top (required)>'

It says I have an undefined method main when I do have it defined in my_file.rb, what I do know about this error is it's usually due to me calling a method before it's defined. Not to sure what I'm doing wrong here though since I thought the method is defined. Any help is greatly appreciated!


Solution

  • I can think of two possible causes for this:

    1) The my_file that's being loaded at runtime may not be the one you think it is. I suggest putting something in there, like a puts or a raise, to see if that's the file really being run.

    You might want to use require_relative instead of require, because that will give you more control over which file gets loaded.

    2) You have 2 describe's. I would recommend removing the inner one.

    Also, there were 2 errors on 1 line in the spec file; here is the corrected version:

        expect {@c.main}.to output("Hello World\n").to_stdout
    

    'World' was not capitalized, and there was no "\n" at the end of "Hello World".