Randall Coding
Randall Coding

Reputation: 483

How do I import my main crate into my test files? Rust doc example doesn't work

I'm setting up unit tests for my rust project and using this guide. The documentation says to do something like this, where "adder" is the project name (if I am not mistaken).

tests/integration_test.rs

use adder;
mod common;

#[test]
fn it_adds_two() {
    common::setup();
    assert_eq!(4, adder::add_two(2));
}

I've done something similar. My folder structure is tests/users.rs where tests/ is right next to src/ as in the example. Here is what my test file actually looks like:

tests/users.rs

use test_project;

#[test]
pub fn create_test() {
    //do things with the modules from main 
}

But I'm getting this error: no external crate 'test_project'

As far as I can tell I'm following the documentation to the letter. Can someone point out what I could be missing here?

Here is my folder structure also:

enter image description here

I have no problems running a dummy test without the imports cargo test so cargo is able to find the tests/ folder without any issues

Here is my Cargo.toml

[package]
name = "test_project"
version = "0.1.0"
authors = ["mcrandall <[email protected]>"]
edition = "2018"

[lib]
name = "errormsg"
path = "errormsg/src/lib.rs"

[dependencies]
diesel = { version = "1.4.5", features = ["sqlite"] }
dotenv = "0.15.0"
download_rs = "0.2.0"
futures = "0.3.12"
futures-util = "0.3.12"
oauth2 = { version = "3.0"}
reqwest = { version = "0.11", features = ["json", "stream", "blocking"] }
serde = { version= "1.0.123", features = ["derive"] }
serde_derive = "1.0.123"
serde_json = "1.0.61"
simple-server = "0.4.0"
tokio = { version = "1", features = ["full"] }
url = "2.2.0"
uuid = { version = "0.8.2", features = ["v4"] }

Upvotes: 4

Views: 3030

Answers (3)

spockwall
spockwall

Reputation: 1

I have the issue when using pyo3 crate. In Cargo.toml I have:

[lib]
path = "src/lib.rs"
name = <lib_name>
crate-type = ["cdylib"]

After I commenting the crate-type, the issue fixed. I also tried the way above mentioned. The Cargo.toml:

[lib]
path = "src/lib.rs"
name = <lib_name>
crate-type = ["cdylib", "lib"] // Error!

But another error message came up. It failed to link with cc. I am not able to find a solution to it, so still have to comment it manually before testing currently.

Upvotes: 0

mike rodent
mike rodent

Reputation: 15642

Anyone encountering this problem (inability to use main package in "tests" directory).

This is not the case with the OP but can also arise if you are using PyO3 (or maybe something else, who knows) which requires you to stipulate the "crate-type" under "[lib]" in Cargo.toml.

For PyO3 you have to do this:

[lib]
crate-type = ["cdylib"]

... which will instantly mean that your "tests" directory can't use your main project.

The solution:

[lib]
crate-type = ["cdylib", "lib"]

... unfortunately this is not a pain-free solution: it apparently means that the library is compiled twice. Much discussion on this and the issues it raises here and here. Problems raised several years ago but apparently nothing done about it as yet.

Upvotes: 1

S&#246;ren
S&#246;ren

Reputation: 879

Make sure that in your Cargo.toml name = "test_project". Also, you can only import it if it is a library Library Documentation.

Looking at your Cargo.toml, the lib section tells cargo that this package exports one lib called errormsg contained in errormsg/src/lib.rs. So test_project will not be available for you, because only one lib is allowed per package why?.

There are two solutions to your problem.
You can either make errormsg a module which you then can import for example with test_project::errormsg in tests/users.rs.
Or you can create a separate package and then import it in the Cargo.toml file:

[dependencies]
errormsg = { version = "0.1", path = "./../errormsg" }

Another way is to use workspaces to group packages, but i'm not really familiar with it.

Upvotes: 2

Related Questions