How to import functions from `src` for testing?

Viewed 1408

I have been trying to understand how to import functions for testing in Rust for hours with no success. I have a project structure that looks like this:

.
├── Cargo.lock
├── Cargo.toml
├── src
│  ├── main.rs
│  └── funcs
│    ├── mod.rs
│    └── hello.rs
└── tests
   └── test_hello.rs

src/funcs/mod.rs:

pub mod hello;

src/funcs/hello.rs:

pub fn hello() {
    println!("{}", "hello!");
}

src/main.rs:

mod funcs;

fn main() {
    funcs::hello::hello(); // this works
}

src/tests/test_hello.rs

mod funcs; // this import does not work!

#[test]
fn add() {
    assert_eq!(2 + 2, 4);
}

#[test]
fn hello_test() {
    assert_eq!(funcs::hello::hello(), "hello");
}

How can I import public functions in src so that they can be used in my testing dir?

3 Answers

Create a src/lib.rs file to put most of the logic of your package into a library crate and export the funcs module there:

pub mod funcs;

Now use the library (which contains the module) from wherever you like. In your case, from both src/main.rs and tests/test_hello.rs:

use <crate>::funcs;

Replace <crate> with the name of your library crate which is the same as the package name and your root folder.

A Rust crate can contain a program and/or a library. Tests can only access a library, not a program (and only the public parts of the library). In your case you have only a program, so you can't have tests. In order for tests to work, you will need to:

  • Split you code into a program (in the main.rs file) and a library (in the lib.rs file).
  • Make sure that any part of the library that you want to use in the program is public.
  • Make sure that any part of the library that you want to test is also public.
  • In main.rs and in the tests, write use foo::hello to access the hello function, replacing foo with the name of your library.

If you want to split the code into modules, declare each module with pub mod mod_name in lib.rs, then import them with use foo::mod_name; in main.rs or in the tests.

Rust considers tests as part of a separate crate, so you have to put use your_crate_name::funcs; at the top of your tests, where your_crate_name is the crate name of your main package as defined in Cargo.toml.

Related