#Test Private Fields in Separate Test File
25 messages · Page 1 of 1 (latest)
All the code is available here in case I left out something.
Yes, for a certain definition of "external"
The rule is always that modules can see the private elements of all their ancestor modules. Just like you can have an inline mod test {} inside your code, you can also have a mod test; and a separate test.rs file
So what do I do to expose the private functions?
I tried doing this:
// tests/test.rs
#[ctf(test)]
mod tests {
use super::*;
#[test]
// test code here
I'm still getting the error: field counter of struct counter_app::App is private.
Tests that can access the private fields of their code go inside src
Specifically, they go in a submodule of the thing being tested
Tests inside tests rather than src are considered integration test, and behave as if they were separate crates
Ah I see. So no way to keep the tests in tests/ if it isn't an public field. Thanks fof the help.
Do you recommend just keeping it in one file or creating a file called lib_test.rs in src/ or something to that effect?
If it's only a few tests (less than 10) then keeping it in the same file is usually how it's done. Otherwise, just do mod tests; and make a tests.rs file.
Alright, sounds like good advice.
Alternatively, you can use pub(crate)
Integration tests, ones in the tests folder sibling to src, are each its own crate, AFAIK
Yes but integration tests are not supposed to use private APIs, else they are not integration tests!
True, I'm just pointing out that making something pub(crate) does not make it visible in the folder where OP's tests were
Right, did not notice
Hmm, how about the cfg macro. It is pretty dirty but can generate two versions of the struct one with public fields
cfg for enabling access for testing is not a really nice solution because there's no way to instruct Cargo "enable this feature if testing"
the closest you can get is required-features which lets you write a test that runs only if the feature is enabled, and then you have to always cargo test --feature=test_stuff or cargo test --all-features to get full test coverage
(though arguably you should test with features anyway … but it's extra work if you don't have any features that aren't for testing)
You'd use a separate crate
have that use the feature that gets you the same structs with public fields
that could work but then to get proper test coverage you need to build excluding that crate sometimes
I'm not saying it is a good solution, but it is a solution
If you want to test private fields, just do it from a module under the module where the struct is