Skip to content

Support mocking of Rng:: gen_range #1020

Closed
@gruszczy

Description

@gruszczy

Background

What is your motivation?

I want to test code that uses rand module. Ideally, I would seed the mock with the random entries I want to produce, so I can confirm the end result is working as expected.

What type of application is this? (E.g. cryptography, game, numerical simulation)

game

Feature request

I am writing a small program that randomly selects an entry from an enum. Sample code:

#[derive(Debug)]
enum SettlementSize {
    VILLAGE,
    TOWN,
    CITY
}

impl Distribution<SettlementSize> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> SettlementSize {
        let res = rng.gen_range(0, 3);
        match res {
            0 => SettlementSize::VILLAGE,
            1 => SettlementSize::TOWN,
            2 => SettlementSize::CITY,
            _ => panic!("Unknown value!")
        }
    }
}

fn get_settlement_size(mut rng: impl RngCore) -> SettlementSize {
    let size: SettlementSize = rng.gen();
    size
}

Now, of course I want to test it. That's why get_settlement_size takes the rng value.

    #[test]
    fn random_human_readable() {
        let rng = StepRng::new(1, 1);
        assert_eq!("Town", get_settlement_size(rng).human_readable());
    }

Unfortunately, this doesn't work. When I added some printlns, the value returned from:

rng.gen_range(0, 3);

is always 0. I copied StepRng code into my test module to add println inside and I see next_u32 and next_u64 called. However, later the code disappears into UniformSampler and at that point it becomes too hard for me to follow.

Ideally, I would mock gen_range directly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-postponeWaiting on something else

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions