Testably vs. TestableIO?
Opened this issue · 3 comments
It seems like these two projects are somehow related (I don't mean necessarily in the sense of their code). TestableIO.System.IO.Abstractions's GitHub site mentions Testably.Abstractions as a "related project" that "provides alternative test helpers and additional abstractions", and it looks to me like at least one main contributor here is also a main contributor there.
Are they intended to be usable together in some complementary way? Is one intended as a replacement for the other? When would I want to use one rather than the other?
For context: I've been using TestableIO for a few weeks, and have not used Testably at all.
Thanks in advance.
Yes, they are indeed related.
Testably uses the interfaces from TestableIO.System.IO.Abstractions so that no changes on the productive code is necessary, when switching the testing library. The testing helpers in this project are much more extensive (e.g. time handling, support for drives, the file system watcher or working with SafeFileHandle
s is possible here, but not in System.IO.Abstractions) and also include further interfaces (ITimeSystem
and IRandomSystem
).
I am currently the main contributor in both projects, but my focus is definitely on the Testably-projects.
If you want to switch, you have to reference Testably.Abstractions.Testing
in your test project and use the MockFileSystem
from there. You don't have to change anything in your productive code!
Thanks. I've tried this out and have been confused by the results. Please forgive me if I am misunderstanding, but I now believe the source of my confusion is your usage of the word "productive" in "You don't have to change anything in your productive code". You've used the word in this confusing-at-least-to-me way on the project's documentation page, too, so I thought it would be best to mention it to you so that you could fix it there:
I now think you don't really mean "productive code", and instead mean "production code", i.e. the "real", non-testing code. At least to me "productive code" doesn't mean that. Instead, it means something like "functioning" or "working" or "useful". So, when I replaced my productive test project's productive code's references to TestableIO.System.IO.Abstractions.TestingHelpers.MockFileSystem with references to Testably.Abstractions.Testing, I was surprised to get a whole bunch of compilation errors.
I see that you seem to have used "productive" in this sense in the "Getting Started" section of the main documentation page too. It's less confusing there, since "productive projects" being explicitly used in contrast to "test projects". But (unless I'm misunderstanding) I'd strongly suggest changing it there to "production" - like I said, it's "less confusing there", but I just mean that in the sense of "it's easier to figure out that what you really meant was 'production', not 'productive'".
Anyway, about all those compilation errors in my productive (but not production) code: Am I understanding correctly that these are expected? It looks to me like Testably's MockFileSystem is not a drop-in replacement for TestableIO's MockFileSystem, lacks a bunch of things like "AddDirectory()" and "MockFileData", and so it's not a surprise that existing test code will have to change. That's fine with me, but I have two specific questions based on what I think I've figured out so far:
(1) Is there a way to add stuff after construction? For example, to replace code like:
var fileSystem = new MockFileSystem();
fileSystem.AddDirectory(someDirectoryName);
Obviously in that simple example, it would be easy enough to change it to use the fluent construction syntax that's suggested in "Getting Started", but there are more complex cases where my existing code would be harder to shoehorn into construction time.
(2) Is there a way to deal with non-Windows things (even if the tests are running on a Windows box)? I see the "Getting Started" example relies on WithDrive()
on "D:" and InitializeIn()
on that drive, which doesn't make sense for Unix-like systems.
Thanks again.
Thanks for the feedback about "productive code" vs "production code". I definitely didn't want to cause confusion and will try to find a less confusing wording.
That said, the compilation errors in your test projects are expected. The MockFileSystem
is not a drop-in replacement!
(1) Is there a way to add stuff after construction? For example, to replace code like:
var fileSystem = new MockFileSystem(); fileSystem.AddDirectory(someDirectoryName);
Yes, either you directly create it with the "normal" syntax (e.g. fileSystem.Directory.CreateDirectory(someDirectoryName)
) or you can use the Initialize
extension methods:
var fileSystem = new MockFileSystem();
fileSystem.Initialize().WithSubdirectory(someDirectoryName);
(2) Is there a way to deal with non-Windows things (even if the tests are running on a Windows box)? I see the "Getting Started" example relies on
WithDrive()
on "D:" andInitializeIn()
on that drive, which doesn't make sense for Unix-like systems.
Of course, the whole file system runs on all platforms. The WithDrive
extension is completely optional, but you can use it even on Unix-Systems to specify certain hardware-requirements, e.g.
var fileSystem = new MockFileSystem();
fileSystem.WithDrive(d => d.SetTotalSize(5));
fileSystem.File.WriteAllText("foo", "some text longer than 5 bytes"); // this will throw an IOException that there is not enough space on the disk.
If you don't need this functionality, just omit the WithDrive
extension.
It would probably be a good idea to improve the README to make this clearer.