Skip to content

First Expectation cannot be overwritten #667

@tgsmith61591

Description

@tgsmith61591

Explanation

Once .expect_foo() is called on a mock instance, the return value cannot be overwritten.

Consider the following example:

    #[mockall::automock]
    trait Kek {
        fn kek(&self) -> u8;
    }
    #[test]
    fn test_kek() {
        let mut kek = MockKek::new();
        kek.expect_kek().returning(|| 1);
        kek.expect_kek().returning(|| 2);

        let got = kek.kek();
        assert_eq!(got, 2, "want 2, got: {}", got); // Oh no, got 1!!!!
    }

So what? Why not just call it once?

Well, imagine a trait that has many methods, and creation of a default mock is placed into a testing fixture, and each test is responsible for setting up its expected return value. Perhaps something like:

#[rstest::fixture]
fn mock_kek() -> MockKek {
        let mut kek = MockKek::new();
        kek.expect_kek().returning(|| u8::default());
        kek.expect_foo().returning(|| u8::default());
        kek.expect_bar().returning(|| u8::default());
        // ...
        kek.expect_qux().returning(|| u8::default());
        kek
}

#[rstest]
fn test_kek(mut mock_kek: MockKek) {
        kek.expect_kek().returning(|| 2);
        let got = kek.kek();
        assert_eq!(got, 2, "want 2, got: {}", got); // Oh no, we get u8::default()!
}

Expected behavior

I would expect that calling .expect_kek() again would allow me to overwrite the default setup in the fixture.
Is there a clear way around this, or is this a case of me just misusing the tool?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions