Reputation: 396
I've used both rspec and minitest for Rails applications and libraries that had straightforward algorithms. By that I mean, if I have
def add(a, b)
a + b
end
that's simple to test. I expect that add(2, 2)
to equal 4
.
But say I have methods dependent on a certain machine.
def device_names
# some code to return an array of device names
end
I would get, e.g., ['CPU', 'GPU', 'DSP']
, but this is completely dependent on my machine. No other person would be able to successfully pass the test if I were just expecting that.
How do you handle cross-environment testing as in the second example? How do you make it generic enough to cover that code for testing?
Upvotes: 0
Views: 91
Reputation: 5398
The piece of code in device_names
method probably calls some methods in other Ruby classes and results of those calls are then manipulated by your code. You can stub those calls and test your method in isolation.
Here's a (silly) example of how to create a stub on any instance of a String class:
String.any_instance.stub(:downcase).and_return("TEST")
Now any call to downcase
on any instance of String will return "TEST". You can play with that in irb
:
irb(main):001:0> require 'rspec/mocks'
=> true
irb(main):002:0> RSpec::Mocks::setup(self)
=> #<RSpec::Mocks::Space:0x10a7be8>
irb(main):003:0> String.any_instance.stub(:downcase).and_return("TEST")
=> #<RSpec::Mocks::AnyInstance::StubChain:0x10a0b68 @invocation_order={:stub=>[nil], :with=>[:stub], :and_return=>[:wit
, :stub], :and_raise=>[:with, :stub], :and_yield=>[:with, :stub]}, @messages=[[[:stub, :downcase], nil], [[:and_return,
"TEST"], nil]]>
irb(main):004:0> "HAHA".downcase
=> "TEST"
Of course, you can also stub methods in single instances, for specific parameters, and so on. Read more on stubbing methods.
Now that you know what will be returned by the platform specific code, you can test your method and always get expected results.
Upvotes: 1