I have a function that will select a random value between a min and a max value. So when I have a test where I test that the value fall between the min and max value. But as there where some failures in my app the test passed some times and some times fails due to the randomness.
Would it be a good idea to override/mock Math.random()
to return 0 and 1 and test that my value is same as max or min value? Or are there better ways to test randomness in JavaScript?
Here is the function that will be used to create the random number:
function constrain(min, max){
return Math.round(Math.random() * (max - min) + min)
}
Generating Javascript Random Numbers Javascript creates pseudo-random numbers with the function Math. random() . This function takes no parameters and creates a random decimal number between 0 and 1. The returned value may be 0, but it will never be 1.
random() is a pseudo-random number as no computer can generate a truly random number, that exhibits randomness over all scales and over all sizes of data sets. However, the pseudo-random number generated by Math. random() is usually sufficient for the needs of nearly any program you may write.
Example: Integer Value Between Two Numbers In JavaScript, you can generate a random number with the Math. random() function. The above program will show an integer output between min (inclusive) to max (inclusive). First, the minimum and maximum values are taken as input from the user.
In JavaScript, random() is a function that is used to return a pseudo-random number or random number within a range. Because the random() function is a static function of the Math object, it must be invoked through the placeholder object called Math.
SinonJS is a JavaScript mocking framework which integrates with all of the major JavaScript Unit Testing frameworks. The adapters will take care of 'reverting' any stubs / mocks that you create during your tests.
// Stub out Math.random so it always returns '4' (chosen by fair dice roll)
sinon.stub(Math, 'random').returns(4);
// Double check that it worked.
equal(Math.random(), 4, "http://xkcd.com/221/");
Generally your tests should pass for all possible values of your non-deterministic code. Maybe have a loop in your test where you do the test say 100 times. That will catch more failures without changing the application code. What you suggested is also an option.
Preferrably, you should have no random element in your test at all. You should feed your method known values, so that you can determine if the result is exactly what you excpect.
If you have random values, you would have to test the method a lot of times, and you are still not sure that you get the exact result that you want, only that you get something in the right range.
If you for example use the current date in your code (new Date()
), then you should provide your method with known dates when testing, otherwise your test will only show that the method works right now. Tomorrow it might fail.
However, I can tell you right away that your method doesn't work well. You should use the floor
method instead of round
, otherwise the lowest and highest values will occur half as often as the other values:
function constrain(min, max){
return Math.floor(Math.random() * (max - min + 1) + min)
}
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