-1

I have a class 'A' that holds an instance of Random, and which simulates rolling a die, e.g. 6 sides, with a result of 1 - 6 being generated on each 'roll'.

I have another class 'B' that may hold a reference to an object of type A, and should delegate to its 'roll' method.

Another person needs to write a unit test to assess that the method in class B is delegating to the 'roll' method in class A correctly. In order to do this I simply need to invoke the method X times and check that the score updates.

Currently in the unit test I have a loop that goes round up to 1000 times and if the score hasn't been updated then I assume it is beyond the realms of possibility that the same number could have been rolled consecutively 1000 times! I have however picked the number 1000 out of thin air. I wanted to pick a more accurate number, based on the actual behaviour of Java's Random class.

From reading the API it says it is states it is "a linear congruential pseudorandom number generator..". What I'm trying to ascertain is based on it using a 48-bit, is there a number of times for which it is impossible for the same value to be repeated. E.g. in my scenario where the numbers 1 - 6 could be generated, is it say impossible to get the same number, e.g. 6, more than 20 times in a row? I'm looking for that information if anyone knows it.

UPDATE -- I'll make the question simpler. With the Java random class, if I call nextInt(6), how many times is it possible for me to receive the same result consecutively. E.g. mathematically is there a limit based on the 48-bit seed and workings of the algorithm of the Random class? I want an answer that states, e.g. "It is categorically impossible to get the same result more than X times" where X is my answer.

Tranquility
  • 3,061
  • 5
  • 23
  • 37
  • place your actual code please – Jordi Castilla Oct 27 '16 at 10:35
  • 3
    It is not very clear what you mean by "check that the score updates". That being said, if you want to test that A is delegating `roll` to B, you should mock B and verify that `roll` has been called on the mock. You could have a look at EasyMock or Mockito for mocking B. – jchampemont Oct 27 '16 at 10:36
  • 2
    A true unit test would mock object A and verify directly that its roll method is called. – Henry Oct 27 '16 at 10:36
  • 1
    Also, when testing code that uses a deterministic pseudo-random number generator, it is useful to specify a seed in the test case. That way, the code should produce exactly the same sequence of events. – Thilo Oct 27 '16 at 10:39
  • Basic mistake, you use a different random generator each time without specifying a seed, therefore taking the standard seed. This means that every time a new random generator with the same seed is created and thus gives the same number. Give your die class a static random generator. And feed it with a proper seed, like the current time. – Aziuth Oct 27 '16 at 10:52
  • I consider your approach viable. After 1000 rolls having the same value every time is so unlikely that you can consider it impossible. To answer your question: If you instantiate your `Random` with a known seed, it’s a matter of trying it out; probably two or three rolls will suffice. If you don’t know the seed, there is no categorical answer saying that the same value is impossible more than N times in a row (not even with N = 2 ^ 48). – Ole V.V. Oct 27 '16 at 11:06
  • Are you wanting to acertain that B calls A, or are you wanting to acertain that the outcome from B is indeed pseudo-random? – Ole V.V. Oct 27 '16 at 11:17

2 Answers2

3

Typically you would try to mock class A (i.e. with Mockito). Here is an SO question/ answer that shows how to verify if a method was called n times.

Community
  • 1
  • 1
Stefan Freitag
  • 3,578
  • 3
  • 26
  • 33
  • import static org.mockito.Mockito.*; -- I cannot use this library in my JDK installation. I do not want to divulge into why. I'll make the question simpler. With the Java random class, if I call nextInt(6), how many times is it possible for me to receive the same result consecutively. E.g. mathematically is there a limit based on the 48-bit seed and workings of the algorithm of the Random class? I want an answer that states, e.g. "It is categorically impossible to get the same result more than X times" where X is my answer. – Tranquility Oct 27 '16 at 10:50
  • 1
    @Tranquility If success or failure of your test depends on the inner workings of the `Random` class, it isn't really a unit test any more, is it? – biziclop Oct 27 '16 at 10:55
1

The PRNG used by Random has only 248 different states according to the documentation. The sequence of numbers generated with nextInt(6) therefore repeats with a period of at most 248.

We can assume that all 6 possible outcomes are generated eventually independent of the seed value, otherwise, the generator is of very bad quality. Therefore, there must be a limit X < 248 satisfying "It is categorically impossible to get the same result more than X times".

To find the smallest such X is however not trivial. The brute force method would generate 248 sucessive numbers and check.

Henry
  • 42,982
  • 7
  • 68
  • 84
  • Many thanks! This is the kind of information I was looking for. To clarify I mean get the same result in X times in a row, so hitting the number 5, X times consecutively. – Tranquility Oct 27 '16 at 11:45