4

How do I access my libraries exported functions inside the create's "tests" directory?

src/relations.rs:

#![crate_type = "lib"]

mod relations {
    pub fn foo() {
        println!("foo");
    }
}

tests/test.rs:

use relations::foo;

#[test]
fn first() {
    foo();
}
$ cargo test
   Compiling relations v0.0.1 (file:///home/chris/github/relations)
/home/chris/github/relations/tests/test.rs:1:5: 1:14 error: unresolved import `relations::foo`. Maybe a missing `extern crate relations`?
/home/chris/github/relations/tests/test.rs:1 use relations::foo;
                                                 ^~~~~~~~~

If I add the suggested extern crate relations, the error is:

/home/chris/github/relations/tests/test.rs:2:5: 2:19 error: unresolved import `relations::foo`. There is no `foo` in `relations`
/home/chris/github/relations/tests/test.rs:2 use relations::foo;
                                                 ^~~~~~~~~~~~~~

I want to test my relations in this separate tests/test.rs file. How can I solve these use issues?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
fadedbee
  • 42,671
  • 44
  • 178
  • 308

2 Answers2

5

Your problem is that, first, mod relations is not public so it is not visible outside of the crate, and second, you don't import your crate in tests.

If you build your program with Cargo, then the crate name will be the one you defined in Cargo.toml. For example, if Cargo.toml looks like this:

[package]
name = "whatever"
authors = ["Chris"]
version = "0.0.1"

[lib]
name = "relations"  # (1)

And src/lib.rs file contains this:

pub mod relations {  // (2); note the pub modifier
    pub fn foo() {
        println!("foo");
    }
}

Then you can write this in tests/test.rs:

extern crate relations;  // corresponds to (1)

use relations::relations;  // corresponds to (2)

#[test]
fn test() {
    relations::foo();
}
Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
  • This answer makes one more level of namespace nesting than required, but is very clear and useful. Are crates modules in their own right, or are crates and modules two forms of namespaces? – fadedbee Oct 15 '14 at 20:33
  • @chrisdew, yes, crates and modules are different. Crates consist of modules; each crate has a nameless top-level module called "crate root" which consists of all of definitions in the top-level file, `lib.rs` in this case. If you remove `pub mod relations` and corresponding braces and leave `fn foo()` at the top level, you won't need second `relations` in `use relations::relations` in tests, because now `fn foo()` will live in the crate root. – Vladimir Matveev Oct 15 '14 at 20:36
  • Crates are units of compilations, and modules are logical units for structuring your code. This is the reason why, for example, you can have mutual dependencies between modules in the same crate but can't have mutual dependencies between crates. – Vladimir Matveev Oct 15 '14 at 20:37
  • Crates create a namespace that is their name, and modules creates deeper namespaces under the crate namespace? Tests within a crate's `/tests` folder must access the crate as if they were "outside" i.e. use `extern`? – fadedbee Oct 16 '14 at 08:04
  • @chrisdew, yes, your assessment is absolutely correct. BTW, it is not widely known, but crate names can have fancy symbols in their names which modules can't, for example, `some-crate` is a valid crate identifier: `extern crate some-crate`. Not sure if such paths can be used in code though, maybe rename with `as` is needed. – Vladimir Matveev Oct 16 '14 at 09:09
  • Thanks, @VladimirMatveev! By the way, I should note, the `extern crate relations` line is no longer needed. You can just use `use relations::relations`. – Yvon Manzi Nov 14 '20 at 16:31
0

The solution was to specify a crate_id at the top of src/relations.rs:

#![crate_id = "relations"]
#![crate_type = "lib"]

pub fn foo() {
    println!("foo");
}

This seems to declare that all the contained code is part of a "relations" module, though I'm still not sure how this is different to the earlier mod block.

fadedbee
  • 42,671
  • 44
  • 178
  • 308