bragboy
bragboy

Reputation: 35542

Is there a way to mock/stub "puts" in Rails

I am printing some custom messages in my application using the puts command. However, I do not want these to be appearing in my Test Output. So, I tried a way to stub puts as shown below. But it still outputs my messages. What am I doing wrong ?

stubs(:puts).returns("") #Did not work out
Object.stubs(:puts).returns("") #Did not work out either
puts.stubs.returns "" #Not working as well
Kernel.stubs(:puts).returns "" #No luck

I am using Test::Unit

Upvotes: 5

Views: 3441

Answers (4)

Jacob Dalton
Jacob Dalton

Reputation: 1703

Using Rails 5 + Mocha: $stdout.stubs(puts: '')

Upvotes: 1

user132447
user132447

Reputation: 1701

So the comments to the original post point to the answer:

Kernel.send(:define_method, :puts) { |*args| "" }

Instead of silencing all output, I would only silence output from the the particular objects that are putsing during your tests.

class TestClass
  def some_method
    ...
    puts "something"
  end
end

it "should do something expected" do
  TestClass.send(:define_method, :puts) { |*args| "" }
  test_class.some_method.should == "abc123"
end

Upvotes: 0

Kelvin
Kelvin

Reputation: 20877

You probably need to stub it on the actual instance that calls puts. E.g. if you're calling puts in an instance method of a User class, try:

user = User.new
user.stubs(:puts)
user.some_method_that_calls_puts

This similarly applies to when you're trying to test puts in the top-level execution scope:

self.stubs(:puts)

Upvotes: 7

Bitterzoet
Bitterzoet

Reputation: 2792

What I would do is define a custom log method (that essentially calls puts for now) which you can mock or silence in test quite easily.

This also gives you the option later to do more with it, like log to a file.

edit: Or if you really want to stub puts, and you are calling it inside an instance method for example, you can just stub puts on the instance of that class.

Upvotes: 1

Related Questions