Forum: RSpec Accessing the model class from within an rspec-rails spec

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cameron B. (Guest)
on 2008-10-29 06:33
(Received via mailing list)
Hi everybody,

New to the list, so apologies if this has been answered elsewhere, but I
didn't find it. I'm trying to build up a plugin of useful rspec macros
for
rails development, eg. things like:

it_should_return_success
it_should_redirect_to { some_url }

I'm basing my ideas off of some stuff technoweenie has done, as well as
a
few others.

One thing I'd love to do is be able to figure out the model class in a
rails
model spec, so I can do something like:

describe User do
  it_should_validate_presence_of :name
end

I can get it working if I pass in User as an argument:

describe User do
  it_should_validate_presence_of User, :name
end

but that feels redundant. Is there a way to access the class itself that
I'm
missing? On the controller spec side, I see there is
controller_class_name,
but that needs to be set with the controller_name method. I could go for
something like that if required, but somehow it seems like it would be
overkill.

Any advice would be greatly appreciated, thanks!!

Cameron
Nick H. (Guest)
on 2008-10-29 23:03
(Received via mailing list)
On 2008-10-28, at 09:09, Cameron B. wrote:
> describe User do
>   it_should_validate_presence_of :name
> end
>
> I can get it working if I pass in User as an argument:
>
> describe User do
>   it_should_validate_presence_of User, :name
> end

Hi Cameron. I haven't played with RSpec's internals at all, but
considering that
     #it_should_validate_presence_of
is nested within
     describe User do
I would imagine that there's a way to grab "User". Have a look at the
structure of the Example, ExampleGroup, etc classes. It'll be stored
in one of those, somewhere.
-Nick
Pat M. (Guest)
on 2008-10-30 05:33
(Received via mailing list)
"Cameron B." <removed_email_address@domain.invalid> writes:

> Is there a way to access the class itself that I'm missing?

described_type

Pat
David C. (Guest)
on 2008-10-30 05:33
(Received via mailing list)
On Tue, Oct 28, 2008 at 8:09 AM, Cameron B. 
<removed_email_address@domain.invalid>
wrote:
> few others.
> describe User do
>   it_should_validate_presence_of User, :name
> end
>
> but that feels redundant. Is there a way to access the class itself that I'm
> missing? On the controller spec side, I see there is controller_class_name,
> but that needs to be set with the controller_name method. I could go for
> something like that if required, but somehow it seems like it would be
> overkill.
>
> Any advice would be greatly appreciated, thanks!!

You're looking for example_group.described_type, which you can get to
like this:

describe Foo do
  described_type # =>Foo

  it "should be Foo" do
    self.class.described_type # => Foo
  end
end

Cheers,
David
Zach D. (Guest)
on 2008-10-30 05:35
(Received via mailing list)
On Wed, Oct 29, 2008 at 12:01 PM, Nick H. <removed_email_address@domain.invalid>
wrote:

>> end
>>
>
> Hi Cameron. I haven't played with RSpec's internals at all, but considering
> that
>    #it_should_validate_presence_of
> is nested within
>    describe User do
> I would imagine that there's a way to grab "User". Have a look at the
> structure of the Example, ExampleGroup, etc classes. It'll be stored in one
> of those, somewhere.


described_type is what you want. This represents the object being
described,
Mike G. (Guest)
on 2008-10-30 05:36
(Received via mailing list)
Part of the testing harness on one of our projects:

module Spec::Example::ExampleGroupMethods
   def model
     self.described_type.to_s.underscore
   end

   def should_require(*attrs)
     raise "should require needs at least one attribute" if attrs.empty?
     model = model()
     attrs.each do |attribute|
       it "should require :#{attribute}" do
         m = Factory.build(model.to_sym)
         m.send("#{attribute}=", nil)
         m.should have(1).error_on(attribute)
       end
     end
   end
...
end

Using FactoryGirl for spinning up instances, but of course easily
tweaked for other mocking.

Mike
Cameron B. (Guest)
on 2008-10-30 05:37
(Received via mailing list)
Hi again,

I think I may have partly found my own answer.

Looking at this gist http://gist.github.com/14050 by Andy F., it
seems
to do much of what I'm looking for right now (thanks, awesome!!).

But playing around with it a bit, calling self.described_type which I
thought would return the class, it's not, it seems to be looking only
for a
module?

      def described_type
        description_parts.find {|part| part.is_a?(Module)}
      end

Is there something I'm missing?

Cameron
Pat M. (Guest)
on 2008-10-30 05:38
(Received via mailing list)
Nick H. <removed_email_address@domain.invalid> writes:

>
> Hi Cameron. I haven't played with RSpec's internals at all, but
> considering that
>     #it_should_validate_presence_of
> is nested within
>     describe User do
> I would imagine that there's a way to grab "User". Have a look at the
> structure of the Example, ExampleGroup, etc classes. It'll be stored
> in one of those, somewhere.

For some reason my emails are getting bounced or delayed or something,
so I'll try again in case my first one didn't go through...

You're looking for described_type

Pat
David C. (Guest)
on 2008-10-30 05:45
(Received via mailing list)
On Tue, Oct 28, 2008 at 8:40 AM, Cameron B. 
<removed_email_address@domain.invalid>
wrote:
>
>       def described_type
>         description_parts.find {|part| part.is_a?(Module)}
>       end
>
> Is there something I'm missing?

Some example groups describe modules, some classes. RSpec supports
both, and Module does it:

$ irb
>> module Foo; end
=> nil
>> Foo.is_a?(Module)
=> true
>> class Bar; end
=> nil
>> Bar.is_a?(Module)
=> true

whereas Class does not.

HTH,
David
Cheers,
David
Scott T. (Guest)
on 2008-10-30 05:46
(Received via mailing list)
On Oct 28, 2008, at 9:09 AM, Cameron B. wrote:

> as a few others.
> describe User do
>   it_should_validate_presence_of User, :name
> end
>
> but that feels redundant. Is there a way to access the class itself
> that I'm missing? On the controller spec side, I see there is
> controller_class_name, but that needs to be set with the
> controller_name method. I could go for something like that if
> required, but somehow it seems like it would be overkill.
>
> Any advice would be greatly appreciated, thanks!!

Why not something like this:

before(:each) { @user = User.new }

it { @user.validate_presence_of(:name) }

Scott
This topic is locked and can not be replied to.