mardi 18 août 2020

Rust: Mocking rand functions with gen_range

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. What am I doing wrong? Can I somehow retain the testability (which means being able to set fixed results for random in my mind)?




Aucun commentaire:

Enregistrer un commentaire