10

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?

Acorn
  • 24,970
  • 5
  • 40
  • 69
turtle
  • 7,533
  • 18
  • 68
  • 97
  • 1
    `mod` *defines* a module; it does not *import* a module. Use `use` to import a module. Should be something like `use crate::funcs;` in `test_hello.rs`. – Jesper Sep 01 '20 at 10:52
  • Thanks for the help. When I use `use crate::funcs;` in `test_hello.rs`, I get the error: `unresolved import crate::funcs no funcs in the root`. I see `mod funcs` in `main.rs`, so I am not sure what that error means. – turtle Sep 01 '20 at 11:02
  • 1
    Make that `pub mod funcs;` in `main.rs` as Acorn suggests in a comment below. – Jesper Sep 01 '20 at 12:25

3 Answers3

7

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.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • 1
    Thanks for the help. When I move `pub mod funcs;` from `main.rs` to `lib.rs` both of which are in the same `src/` directory, I now get the error that `file not found for module funcs`. Rust further states that `help: to create the module `funcs`, create file "src/lib/funcs.rs"`. – turtle Sep 01 '20 at 11:40
  • Are you using the 2018 edition? – Acorn Sep 01 '20 at 11:45
  • Yes, I am using the 2018 edition. – turtle Sep 01 '20 at 11:46
  • Strange, that should work. – Acorn Sep 01 '20 at 11:54
  • My issue appears to be that I can't use `mod funcs` in `lib.rs`, but it works perfectly fine in `main.rs`. So far, I really like Rust the language, but imports/exports are really difficult to me. – turtle Sep 01 '20 at 11:58
  • 1
    It should be `pub mod funcs;`, since you want to access it from outside the library crate. I suggest starting from scratch and first making a simple binary + library package work, then add a module in its own file, then move it into its own folder, etc. – Acorn Sep 01 '20 at 12:05
  • Cheers. Thanks for the help. I'll do that. Much appreciated. – turtle Sep 01 '20 at 12:41
1

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.

Jmb
  • 18,893
  • 2
  • 28
  • 55
0

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.

Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • Thanks for the help. In my Cargo.toml file, my main package is named `hello`. If I add `use hello::funcs;` to the top of `test_hello.rs` file, I get the error: `use of undeclared type or module hello`; – turtle Sep 01 '20 at 11:18