RSpec With Namespaced Dummy Classes + Eigenclass Fun

29 Mar 2016, by Sia Sajjadi

Generally, you don't need to use dummy classes with rspec.

To clarify

Use doubles if you can!

The rspec mocks and stubs work well and they offer some protection against mocks/stubs becoming out of sync with the objects that they are imitating.

But some times you need a dummy class (or feel like you do anyway)

How to RSpec & Namespaced Dummy classes

First things first, I don't want

class Dummy

nor do I want

class SomeAnnoying::Namespace::ForAnExample::Dummy


class SomeAnnoying::Namespace::ForAnotherExample::Dummy

Option 1 sucks.
Option 2 is better, if done once only
Option 3 is the same as 2, for n example groups you may need up to n namespaces that need naming, consideration, etc.

This is annoying_

A yummy way

In spec/support/helpers/dummy_class_helpers.rb

module DummyClassHelpers

  def dummy_class(name, &block)
    let(name.to_s.underscore) do
      klass =

      self.class.const_set name.to_s.classify, klass


In spec/spec_helper.rb

# skip this if you want to manually require
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}

RSpec.configure do |config|
  config.extend DummyClassHelpers

And finally in your specs you can do

RSpec.shared_examples "JsonSerializerConcern" do


  dummy_class(:dummy_serializer) do
     def self.represent(object)

  describe "#serialize_collection" do
    it "wraps a record in a serializer" do
      expect(dummy_serializer).to receive(:represent).with(an_instance_of(dummy)).exactly(3).times

      subject.serialize_collection [,,]

Now you have:

> dummy
=> RSpec::ExampleGroups::ApplicationController::BehavesLikeJsonSerializerConcern::SerializeCollection::Dummy
> dummy_serializer
=> RSpec::ExampleGroups::ApplicationController::BehavesLikeJsonSerializerConcern::SerializeCollection::DummySerializer

Nice automatic, no?

Eigenclass fun

As an aside, sometimes you can do crazy stuff like:

  dummy_class :dummy do
    def errors
      @errors ||= do |o|
        def o.full_messages


eigenclasses are also known as singletons

The instances of the dummy class above have a method errors such that instance_of_dummy.errors returns an instance of Object. This instance of object has the method full_errors defined on it, such that

> instance_of_object = instance_of_dummy.errors
> instance_of_object.full_messages
=> []

But if we do

=>  NoMethodError: undefined method `full_messages' for #<Object:0x0055fd025fee98>

What we have is an object who's behaviour is defined by it's class as well as it's eigenclass. The full_messages method exists on the eigenclass for this instance, no others.

It's useful because every object in ruby has an eigenclass
Anything defined on or scoped to an eigenclass is only shared by inheritance, which is a non-issue for the instances of classes unless you're doing serious voodoo.

It also means that you can quickly mock up a specific behaviour without having to define classes, structs or doubles. Not that there's anything wrong with that. But this works too :)

Cookies help us deliver our services. By using our services, you agree to our use of cookies.