testingrustmocking

Rust mocking `std::process::Child` for test?


I have an application that spawns a long running Child process. I want to test the logic of the application and the child struct is not really needed for this, I've looked at several mocking frameworks like mockall or faux. But can't really see how I could mock a simple external struct? Any help are really appreciated.


Solution

  • There's no way to replace the behavior of std::process::Command and std::process::Child outright. However, there is a way to change what actually happens — change the command that is executed!

    1. Modify your code so that there is some way to configure (“dependency inject”) the path of the child process. (This might also be useful in non-test scenarios!)
    2. Create the file src/bin/test-child.rs whose main() function has whatever behavior you want the test child to have.
    3. In your test code (which must be located in tests/, an “integration test”, not within the application code), pass env!("CARGO_BIN_EXE_test-child") as the path to the program the code under test should spawn. (This environment variable is set automatically by Cargo.)

    Taking this approach, instead of an in-process mock, means that your test can be more realistic; it does not call a mock that might be subtly different from std, but in fact starts a real process. The required configuration might also be useful when packaging/deploying your application, since it allows complying with requirements about where the child program must be stored, or selecting a different version at run time.