Rspec singleton NoMethodError #new

Hi Guys,

I’m attempting to build a test for a singleton class…

Test.rb:

require ‘singleton’

class Test
include Singleton
end

As I understand it, this should make #new private but make available
#instance.

I want to test this behavior and here is my test script:

test_spec.rb:


require ‘spec_helper’

describe Test do

describe “#new” do
it “new is a private method - generic error” do
expect(Test.new).to raise_error
end

it "new is a private method - NoMethodError" do
  expect(Test.new).to raise_error(NoMethodError)
end

it "new is a private method - RuntimeError" do
  expect(Test.new).to raise_error(RuntimeError)
end

end

describe “#instance” do
it “returns a new test object” do
expect(Test.instance).to be_a Test
end
end
end

The results are fine for #instance (it passed) but all of the #new tests
fail.

Results:

$ rspec spec -fd -c

Test
#new
new is a private method - generic error (FAILED - 1)
new is a private method - NoMethodError (FAILED - 2)
new is a private method - RuntimeError (FAILED - 3)
#instance
returns a new test object

Failures:

  1. Test#new new is a private method - generic error
    Failure/Error: expect(Test.new).to raise_error

    NoMethodError:
    private method `new’ called for Test:Class

    ./spec/test_spec.rb:7:in `block (3 levels) in <top (required)>’

  2. Test#new new is a private method - NoMethodError
    Failure/Error: expect(Test.new).to raise_error(NoMethodError)

    NoMethodError:
    private method `new’ called for Test:Class

    ./spec/test_spec.rb:11:in `block (3 levels) in <top (required)>’

  3. Test#new new is a private method - RuntimeError
    Failure/Error: expect(Test.new).to raise_error(RuntimeError)

    NoMethodError:
    private method `new’ called for Test:Class

    ./spec/test_spec.rb:15:in `block (3 levels) in <top (required)>’

Finished in 0.00225 seconds (files took 0.19674 seconds to load)
4 examples, 3 failures

Failed examples:

rspec ./spec/test_spec.rb:6 # Test#new new is a private method - generic
error
rspec ./spec/test_spec.rb:10 # Test#new new is a private method -
NoMethodError
rspec ./spec/test_spec.rb:14 # Test#new new is a private method -
RuntimeError

I’m sure I missed something here - any suggestions?

TIA

Steve

Before it calls the method expect, it evaluates its argument, which
raises an error. Taking a look at the rspec docs, you should pass a
block to expect so that it can catch the error:

expect { … }.to raise_error
expect { … }.to raise_error(ErrorClass)
expect { … }.to raise_error(“message”)
expect { … }.to raise_error(ErrorClass, “message”)

Dansei Yuuki wrote in post #1179676:

Before it calls the method expect, it evaluates its argument, which
raises an error. Taking a look at the rspec docs, you should pass a
block to expect so that it can catch the error:

expect { … }.to raise_error
expect { … }.to raise_error(ErrorClass)
expect { … }.to raise_error(“message”)
expect { … }.to raise_error(ErrorClass, “message”)

Thanks for that, Dansei. Spot on.