I have a method that does something like this:
def some_method chance = rand(4) if chance == 1 do # logic here else # another logic here end end
When I use RSpec to test this method, rand(4)
inside it always generates 0. I am not testing rand
method of Rails, I am testing my method. What is a common practice to test my method?
Running tests by their file or directory names is the most familiar way to run tests with RSpec. RSpec can take a file name or directory name and run the file or the contents of the directory. So you can do: rspec spec/jobs to run the tests found in the jobs directory.
RSpec is a unit test framework for the Ruby programming language. RSpec is different than traditional xUnit frameworks like JUnit because RSpec is a Behavior driven development tool.
RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.
There are two approaches I would consider:
Approach 1:
Use a known value of seed in srand( seed )
in a before :each
block:
before :each do srand(67809) end
This works across Ruby versions, and gives you control in case you want to cover particular combinations. I use this approach a lot - thinking about it, that's because the code I was testing uses rand()
primarily as a data source, and only secondarily (if at all) for branching. Also it gets called a lot, so exerting call-by-call control over returned values would be counter-productive, I would end up shovelling in lots of test data that "looked random", probably generating it in the first place by calling rand()
!
You may wish to call your method multiple times in at least one test scenario to ensure you have reasonable coverage of combinations.
Approach 2:
If you have branch points due to values output from rand()
and your assertions are of the type "if it chooses X, then Y should happen", then it is also reasonable in the same test suite to mock out rand( n )
with something that returns the values you want to make assertions about:
require 'mocha/setup' Kernel.expects(:rand).with(4).returns(1) # Now run your test of specific branch
In essence these are both "white box" test approaches, they both require you to know that your routine uses rand()
internally.
A "black box" test is much harder - you would need to assert that behaviour is statistically OK, and you would also need to accept a very wide range of possibilities since valid random behaviour could cause phantom test failures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With