8

I need to write some junit tests on Java code that calls Math.random(). I know that I can set the seed if I was instantiating my own Random object to produce repeatable results. Is there a way to do this also for Math.random() ?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Kevin
  • 11,521
  • 22
  • 81
  • 103

3 Answers3

12

The method Math.random() uses a private static field:

private static Random randomNumberGenerator;

If you really really need to set this to a new Random(CONSTANT_SEED) (for instance you need to JUNit test code which you have no control over) you could do so by using reflection.

rsp
  • 23,135
  • 6
  • 55
  • 69
  • 8
    Could you possibly elaborate on the reflection part of your answer please? – Lynden Shields May 21 '12 at 04:51
  • As of Java 8 (or maybe it was always like this) this is hidden slightly further away - there is a private static final `RandomNumberGeneratorHolder` class in Math that then holds a static final `Random`. – rococo May 25 '19 at 20:04
9

How about creating an instance of Random yourself and using that instead? Math.random() creates one and uses that, so I don't think that you can mess with its seed. If you create a Random and use it directly, however, you can set the seed for that when you create it, and/or you can call setSeed() on it later.

Jonathan M Davis
  • 37,181
  • 17
  • 72
  • 102
3

Set it with instance of Random with your seed or just extend the methods to return values you need

        Field field = Math.class.getDeclaredField("randomNumberGenerator");
        field.setAccessible(true);
        field.set(null, new Random() {

            @Override
            public double nextDouble() {
                return 1;
            }

        });
iTake
  • 4,082
  • 3
  • 33
  • 26