0

I work in a workspace with dozens of crates. One of those crates exposes a trait. As a mock, I implement that trait for () with unimplemented! in every function (they're not actually used). I'd like that implementation to be available from the other crates, but only during the tests: what is the idiomatic way (the handiest) to do so?

For now, the implementation is behind a mock feature, and I add this crate with the mock feature as a dev dependency in a random crate. That forces the compiler to take that implementation into account during the tests. It's an ugly hack, so I'd rather have another way.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Boiethios
  • 38,438
  • 19
  • 134
  • 183
  • Why not implement the trait in the test crate for a type `struct Dummy;` defined in that same test crate rather than for `()`? – mcarton Apr 02 '21 at 15:19
  • It looks like your question might be answered by the answers of [What is an idiomatic way to have shared utility functions for integration tests and benchmarks?](https://stackoverflow.com/q/44539729/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Apr 02 '21 at 15:21
  • @Shepmaster I would create a crate for utilities, like some functions, but it would be kinda weird for trait implementations – Boiethios Apr 02 '21 at 15:38
  • @Boiethios there are three separate answers on that post. – Shepmaster Apr 02 '21 at 15:40

1 Answers1

0

Items gated with test are not exported from a crate, even for crates that use it as a dev dependency.

As of Rust 1.51.0, you can work around that by using a custom feature.

In Cargo.toml:

[features]
test-traits = []

In the code:

#[cfg(feature = "test-traits")]
impl MyTrait for MyStruct {}

In crates that depend on it, you can enable the new resolover:

[package]
resolver = "2"

And add a dev dependency that enables the feature:

[dev-dependencies]
your_crate = { version = "1.0", features = ["test-traits"] }

Without the new resolver enabled all features are additive across targets, so enabling the feature in dev-dependencies would enable it for non-test code too. With the new resolver this is now handled more like you would expect.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204