mockito icon indicating copy to clipboard operation
mockito copied to clipboard

Mocks leak across tests

Open dbr opened this issue 5 years ago • 2 comments

I had one test which setup a few mocks. I then started writing a second test which used some of the same endpoints

When I ran the tests, I expected them to fail (and was going to use the error messages to help setup the required mocks), but to my surprise they passed. If I use --test-threads=1 things work as expected

I think this is a side-effect of #35 - the tests will only be made single-threaded if they create mocks - which didn't work in my case as the second test did not (yet) have any mock calls

I suspect there isn't a simple solution to this; more likely only a structural change like #92 would prevent this

Repro case:

[dbr@slate:~/Desktop/mocktest]$ cat Cargo.toml
[package]
name = "mocktest"
version = "0.1.0"
authors = ["dbr <[email protected]>"]
edition = "2018"

[dependencies]
mockito = "0.23.3"
attohttpc = "*"
[dbr@slate:~/Desktop/mocktest]$ cat src/main.rs
fn main() {
    println!("Hello, world!");
}

#[test]
fn test_video_list() {
    let _m = mockito::mock("GET", "/search").with_body("search").create();

    let _m2 = mockito::mock("GET", "/details")
        .with_body("details")
        .create();

    let r1 = attohttpc::get(format!("{base}/search", base = &mockito::server_url()))
        .send()
        .unwrap();
    assert_eq!(r1.text().unwrap(), "search");
    let r2 = attohttpc::get(format!("{base}/details", base = &mockito::server_url()))
        .send()
        .unwrap();
    assert_eq!(r2.text().unwrap(), "details");
}

#[test]
fn test_metadata() {
    let r = attohttpc::get(format!("{base}/details", base = &mockito::server_url()))
        .send()
        .unwrap();
    assert_eq!(r.text().unwrap(), "details");
}
[dbr@slate:~/Desktop/mocktest]$ cargo test -- --test-threads=2
    Finished test [unoptimized + debuginfo] target(s) in 0.05s
     Running target/debug/deps/mocktest-5f133f3e04875438

running 2 tests
test test_metadata ... ok
test test_video_list ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

[dbr@slate:~/Desktop/mocktest]$ cargo test -- --test-threads=1
    Finished test [unoptimized + debuginfo] target(s) in 0.04s
     Running target/debug/deps/mocktest-5f133f3e04875438

running 2 tests
test test_metadata ... FAILED
test test_video_list ... ok

failures:

---- test_metadata stdout ----
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `""`,
 right: `"details"`', src/main.rs:28:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    test_metadata

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--bin mocktest'

dbr avatar Feb 29 '20 02:02 dbr

nice catch and thanks for reporting. I would also favour #92 as a solution rather than going back to the --test-threads=1 days.

lipanski avatar Mar 08 '20 11:03 lipanski

I got bit by this too, but was confused because I did have a mock in both tests:

#[test]
fn visit() {
    let m = mockito::mock("POST", "/demo").with_status(200).create();
    let res =
        Client::new().post(&format!("{}/demo", mockito::server_url())).send();
    m.assert();
    res.unwrap().error_for_status().unwrap();
}

#[test]
fn dont_visit() {
    let _m = mockito::mock("GET", "/").with_status(404); // add a mock to account for #111
    let res = Client::new().post(&format!("{}/demo", mockito::server_url())).send();
    _m.expect(0);
    res.unwrap().error_for_status().unwrap_err();
}

Tiny typo though! dont_visit() is missing a call to .create(). The fix for #112 should have helped me spot this, but since I don't have logging configured I missed it. Just wanted to share in case anyone else hits this behavior and is confused.

dimo414 avatar Jan 25 '21 22:01 dimo414

I think this should be fixed in https://github.com/lipanski/mockito/releases/tag/0.32.0

lipanski avatar Feb 10 '23 14:02 lipanski