Does Minitest have something similar to allow_any_instance_of from RSpec?

Viewed 1141

From Docs

rspec-mocks provides two methods, allow_any_instance_of and expect_any_instance_of, that will allow you to stub or mock any instance of a class. They are used in place of allow or expect:

allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")

Is there something close to this feature to mock method for all instances of class with Minitest?

2 Answers

According to the Minitest docs you can only mock single instances.

https://github.com/seattlerb/minitest#mocks-

Without seeing the whole code it's hard to judge but might be that your architecture could be improved. For instance you could use dependency injection to avoid the allow_any_instance_of and also make your class more extensible.

Instead of doing

class Foo
  def initialize
    @widget = Widget.new
  end

  def name
    widget.name
  end
end

and doing in your test

it "does expect name" do
  allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")

  Foo.new.name
end

You could inject the widget class like this

class Foo
  def initialize(widget_class = Widget)
    @widget = widget_class.new
  end

  def name
    widget.name
  end
end

and in your spec

it "does expect name" do
  widget = double()
  widget.stub(:name) { 'a name' }

  foo = Foo.new(widget)

  expect(foo.name).to eq('a name')
end

The code is now follows open-closed principle and is more extensible. But hard to judge without seeing your code if this is a viable solution for you.

Summarised this in a blog article here https://sourcediving.com/testing-external-dependencies-using-dependency-injection-ad06496d8cb6

After an year, I found the detailed answer for this question: there is no such feature in minitest and here is why:

  1. It doesn't fit the vision of Minispec authors
  2. It can break the behavior of stub in some cases.

But there is a gem that adds stub_any_instance for the scope of block. The gem is also listed in Known Extensions of Minitest.

Related