Mock an external struct with private fields

I'm new to Rust. I have the below method that accepts a reference to walkdir::DirEntry external struct. I'm trying to unit test this method.

fn is_matching_file(entry: &DirEntry) -> bool { ... }

Now an instance of walkdir::DirEntry struct cannot be constructed with struct literal syntax due to inaccessible fields. And it doesn't have a public constructor. Meaning I cannot create an instance of walkdir::DirEntry struct in my crate.

Is it even possible to mock walkdir::DirEntry external struct? Any ideas on how to unit test the above method?

No.

You can only swap one object out for another when there is some level of polymorphism involved. Typically this means passing in a &dyn SomeDirEntryTrait or making is_matching_file() generic over E: SomeDirEntryTrait. From there, you can provide your own mock implementation.

There are a couple ways you could test this.

The easiest method is to use the tempfile crate to create a temporary directory and call is_matching_file() on real files which do/don't satisfy your condition.

Alternatively, you could look at what is_matching_file() actually checks and only pass that information in. For example, if you only care about the file's path then maybe you just need to accept a &Path. So we would be tying is_matching_file() to properties of a thing (which is just data) rather than the thing itself (which requires identity - i.e. you literally have a walkdir::DirEntry to check).

I find the latter method leads to much better API design and maintainability in the long run. Plus it avoids doing IO in a test, which is very important for keeping a tight edit-compile-test cycle.

2 Likes

Thank you !!!