CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/rust-unit-tests

Rust unit testing with the built-in `cargo test` harness - `#[test]` in `#[cfg(test)] mod tests` blocks, `assert_eq!` / `assert_ne!` / `assert!` macros, `#[should_panic(expected)]`, `Result<(), E>` test returns, integration tests in `tests/`, doc tests in `///` comments, runner flags (`--test-threads=1`, `--nocapture`, `--ignored`), `#[ignore]` marking, coverage via cargo-llvm-cov / tarpaulin, and Criterion benchmarks on stable. Includes framework choice (stdlib `#[test]` is the default; rstest for 4+ parameterized case pairs or shared fixtures via references) and test-authoring conventions (inline `#[cfg(test)]` placement, assertion-macro selection, async runtime requirements). References cover rstest parametrize + fixtures and Rust mocking with mockall (`#[automock]` / `mock!`). Use for any Rust unit-test task: writing tests, testing panics or Results, doc tests, coverage gates, benchmarks, or CI wiring.

72

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

rust-mocking.mdreferences/

Rust mocking - mockall (reference)

Companion reference for rust-unit-tests. A test double (per ISTQB Glossary) replaces a real dependency so the subject under test runs in isolation. mockall is the community-standard Rust mocking crate; use it when a unit test reaches a database, HTTP client, file system, or any trait boundary. For tests that do not cross a trait boundary, prefer real objects or simple stubs.

Per docs.rs/mockall/latest/mockall:

[dev-dependencies]
mockall = "0.14.0"

Two entry points: #[automock] for traits you own; mock! for structs or traits defined in external crates.

#[automock] on a trait

Applying #[automock] generates a MockTraitName struct in the same module:

use mockall::automock;
use mockall::predicate::*;

#[automock]
pub trait Cache {
    fn get(&self, key: &str) -> Option<String>;
    fn set(&mut self, key: &str, value: String);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_lookup_hits_cache() {
        let mut mock = MockCache::new();

        mock.expect_get()
            .with(eq("user:42"))
            .times(1)
            .returning(|_| Some("alice".to_string()));

        let result = lookup(&mock, "user:42");
        assert_eq!(result, Some("alice".to_string()));
    }
}

Expectations are verified automatically when the mock is dropped: a declared times(1) with no call panics on drop and fails the test.

mock! macro for external traits and structs

Use mock! when the trait lives in a dependency you cannot annotate:

use mockall::mock;

mock! {
    pub HttpClient {}
    impl reqwest_like::Client for HttpClient {
        fn get(&self, url: &str) -> String;
        fn post(&self, url: &str, body: &str) -> String;
    }
}

#[test]
fn test_fetch_uses_get() {
    let mut client = MockHttpClient::new();

    client.expect_get()
        .with(eq("https://api.example.com/v1/data"))
        .times(1)
        .return_once(|_| r#"{"ok":true}"#.to_string());

    let result = fetch_data(&client);
    assert!(result.contains("ok"));
}

Expectation methods

MethodBehaviour
.times(n)Requires exactly n calls
.times(..)Any number (range syntax)
.with(matcher)Argument predicate from mockall::predicate::*
.returning(closure)Computes return value via FnMut
.return_once(closure)Consumes an FnOnce (for non-Clone returns)
.return_const(value)Clones and returns a constant
.never()Asserts the method is never called

Common predicates (mockall::predicate::*): eq(v), ne(v), lt(v), gt(v), function(fn), always(), never().

Anti-patterns

Anti-patternWhy it failsFix
Mock every dependencyTests verify mock wiring, not behaviorMock only true isolation boundaries
Missing #[cfg(test)] on the mock moduleMock types compiled into the release binaryWrap MockXxx usage in #[cfg(test)]
mock! when #[automock] sufficesVerbose boilerplate for owned traits#[automock] for traits in your crate

Limitations

  • #[automock] doesn't support some advanced generic trait patterns - fall back to mock! with explicit type parameters.
  • Expectations verify on drop; with multiple mocks in scope, drop-order panics can produce confusing test output.

References

  • mockall-docs - mockall crate documentation
  • istqb-double - ISTQB test-double definition
  • Go mocking (gomock, testify/mock) → go-unit-tests references/go-mocking.md

SKILL.md

tile.json