Search code examples
ruby-on-railsrubyrspecrspec-rails

Rspec 3: can't check class type


Observe:

class BaseValidator; end
class DefaultValidator < BaseValidator; end

Rspec 3.1:

describe ValidatorFactory do
    context "creating DefaultValidator" do
        subject { ValidatorFactory.validator('default') }
        it {is_expected.to be_a(DefaultValidator)}
        it {is_expected.to be_kind_of(BaseValidator) }
    end
end

Prints me this:

Failure/Error: it {is_expected.to be_a(DefaultValidator)}
   expected DefaultValidator to be a kind of DefaultValidator

Failure/Error: it {is_expected.to be_kind_of(BaseValidator) }
   expected DefaultValidator to be a kind of BaseValidator

However, this works:

...
    it {is_expected.to be(DefaultValidator)}
    it {is_expected.to be < (BaseValidator) }
...

ValidatorFactory.rb

class ValidatorFactory
    def self.validator(type)
    case type.downcase
    when 'default'
        DefaultValidator
    else
        BaseValidator
    end
end

Now, I could not find anythyng about be() and be < for class type maching in RSpec docs.

Am I using "be_a" and "be_kind_of" in a wrong way?


Solution

  • Your validator method is returning the class DefaultValidator and/or BaseValidator. In other words, those are not instances of those classes, but their class is Class.

    The be_a and be_a_kind_of matchers are for asserting that an object is an instance of the Class or Module argument that is passed to them.

    That's why your first code sample fails, but the second one passes. The second code snippet is testing Class instances, not instances of your validator.