Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing mocks as and when necessary #1081

Closed
sameera opened this issue Jan 25, 2024 · 4 comments
Closed

Providing mocks as and when necessary #1081

sameera opened this issue Jan 25, 2024 · 4 comments
Labels
state: needs discussion Issues that need further discussion type: enhancement Issues that propose new functionality

Comments

@sameera
Copy link

sameera commented Jan 25, 2024

Problem:

I have a parser that iterates through the file system and parses each file one by one. The functionality is built around IEnumerables and needs to ensure that the next file is read for parsing only after all downstream functions are done processing the previous one.
To test for this, I want to setup a mock for File.ReadAllText and ensure that it's not being called until again the previous file is done.
I could do this by setting up a mock for IFile and checking calls to ReadAllText as that's the only op I do on IFile type. I do have few other calls to other file system objects that I don't want to mock/change. If MockFileSystem.File was settable, I can assign the mock for this test only without changing anything about the other tests.

Proposed solution:
Provide setters for MockFileSystem.File and MockFileSystem.Directory (for consistency and possible similar use cases).

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Alternatives:
For such tests, setup a mocked IFileSystem from scratch with all objects and methods mocked. This could be tedious in many cases.

@sameera sameera added state: needs discussion Issues that need further discussion type: enhancement Issues that propose new functionality labels Jan 25, 2024
@sameera sameera changed the title Providing mocks as an when necessary Providing mocks as and when necessary Jan 25, 2024
@vbreuss
Copy link
Member

vbreuss commented Feb 3, 2024

I am not sure, I understand your use case, @sameera.

Do you use a mocking library like Moq or NSubstitute? If so, it should be easy to not use MockFileSystem at all and simply mock the IFileSystem or IFile interface itself.
Mixing the In-Memory Filesystem with a mock doesn't make sense to me, as you could then run in the situation that you write to a file via the mock and when you later read it from the In-Memory file system, you will get a FileNotFoundException.

@sameera
Copy link
Author

sameera commented Feb 6, 2024

At a very high-level, the use case was to test that certain file operations are not being done over and over. So, we'd want our unit test to test that certain file system APIs (like File.ReadAllText) are not being called more than once. There are other file system operations along this execution path, so we don't want to have to replace all of them with mock code.
BTW, while I'm not yet fully familiar with this concept or library, it might be that Typemock's Isolators are a solution for this.

@vbreuss
Copy link
Member

vbreuss commented Feb 21, 2024

The idea behind an In-Memory file system is, that it should behave (more or less) exactly like a real file system. If we would allow replacing single calls, this would result in much more complexity, as we could no longer rely on any consistent behavior. For this I would not like to introduce any (backward-incompatible) changes in the interface.

That being said, if I understand your use case correctly, you would like some "analytical" information about which method is called how often. This could be an interesting extension to the current MockFileSystem. If you would like to work on such a feature, I would be happy to discuss more details...

@sameera
Copy link
Author

sameera commented Mar 27, 2024

Closing the loop on this:
I was able to achieve this using NSubstitute:

// Setup a substitute to proxy MockFileSystem
 _fileSystem = Substitute.ForPartsOf<MockFileSystem>();
// Setup a MockFile instance that we can observe
_fileSystem.File.Returns(Substitute.ForPartsOf<MockFile>(_fileSystem));

// ....
// Other setup and testing code
// ...

// Test (in this case, verify that a file read happened only once)
_fileSystem.File.Received(1).ReadAllText(Arg.Any<string>());

@sameera sameera closed this as completed Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: needs discussion Issues that need further discussion type: enhancement Issues that propose new functionality
Projects
None yet
Development

No branches or pull requests

2 participants