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

Doc change: clarify difference between clear and unmock #184

Closed
erikhuizinga opened this issue Nov 23, 2018 · 10 comments
Closed

Doc change: clarify difference between clear and unmock #184

erikhuizinga opened this issue Nov 23, 2018 · 10 comments
Labels
docs Documentation change request fixed fixed in master

Comments

@erikhuizinga
Copy link
Contributor

Expected Behavior

There is documentation explaining the specific use cases for the various unmock functions w.r.t. the clear functions, and the differences.

Current Behavior

It is unclear what 'clear' vs. 'cancel' vs. 'unmock' mean. Take a look at the two following pieces of documentation.

The documentation of, for example, unmockAll:

Cancels object, static and constructor mocks.

What does 'unmock' mean? What does 'cancel' mean? Are they the same? When do I unmock?

The documentation of, for example, clearAllMocks:

Clears all regular, object, static and constructor mocks.

What does 'clear' mean w.r.t. 'unmock' or 'cancel'?

Context

  • MockK version: 1.8.13.kotlin13
@oleksiyp
Copy link
Collaborator

True, even worse.

I am not able to finalize understanding of what cases should be handled by what functions. Which patterns are right to effectively clean-up it. And in the code there is a mess caused by compatibility with previous implementations (as there was an attempt to change things to better).

Simply of course, unmockk is transforming all the classes back. And clear just resets internal state of objects associated with mock. This should be mentioned somewhere

I think the problem is that I am myself not using my library a lot and that's why hard to understand all this cleanup stuff. It is a bit coming to me as a nightmare from time to time

@erikhuizinga
Copy link
Contributor Author

erikhuizinga commented Nov 24, 2018

Would you consider the following a good practise?
https://youtu.be/RX_g65J14H0?t=1177
In that video, Philipp Hauer suggest to clear mocks before each test (@BeforeEach). I guess the main difference between clear and unmock is that clear resets a mock object's state (e.g. how it behaves and its internal counters), while unmock truly removes the mock object (I guess from MockK's mock object collection/repository/dependency graph/whatever)?

If that's correct and if you agree with such usage, I can make a PR suggesting changes to some documentation and MockK's readme.

I wonder what would be a use reason to unmock an object. Maybe to unmock static mocks so that between tests you can use or mock them differently?

@oleksiyp oleksiyp changed the title Clarify difference between clear and unmock Doc change: clarify difference between clear and unmock Dec 25, 2018
@oleksiyp oleksiyp added docs Documentation change request and removed help wanted labels Dec 25, 2018
@oleksiyp oleksiyp added this to To do in MockK features Dec 25, 2018
@erikhuizinga
Copy link
Contributor Author

My current practice is the following:

  • Before a test class instantiate mocks once (as this can be costly).
  • After each test call clearAllMocks.
  • After the test class call unmockkAll once to reset anything MockK might have in memory globally, to prevent leaking mocks to other test classes.

Would you consider this good practice (in general)? If so, please consider suggesting this in the documentation. Currently only unmockkAll is used in an example (after each test function instead of after a test class) and clearAllMocks is not used in an example at all.

@sorokod
Copy link

sorokod commented Jun 13, 2019

Would you consider the following a good practise?
https://youtu.be/RX_g65J14H0?t=1177
In that video, Philipp Hauer suggest to clear mocks before each test (@BeforeEach). I guess the main difference between clear and unmock is that clear resets a mock object's state (e.g. how it behaves and its internal counters), while unmock truly removes the mock object (I guess from MockK's mock object collection/repository/dependency graph/whatever)?
...

I observe the opposite behaviour (v. 1.9.3) where only clearAllMocks "truly removes the mock object".

@stale
Copy link

stale bot commented Aug 12, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just ask to put an important label.

@stale stale bot added the stale label Aug 12, 2019
@stale stale bot closed this as completed Aug 19, 2019
@adam-hurwitz
Copy link

adam-hurwitz commented Sep 12, 2019

This is the correct distinction as confirmed by @oleksiyp from his Twitter response.

Clear - Deletes internal state of objects associated with mock resulting in empty object.
Unmock - Re-assigns transformation of classes back to original state prior to mock.

@oleksiyp
Copy link
Collaborator

oleksiyp commented Nov 2, 2019

Added to docs: https://mockk.io/#clearing-vs-unmocking

@oleksiyp oleksiyp added fixed fixed in master and removed stale labels Nov 2, 2019
@oleksiyp oleksiyp removed this from To do in MockK features Nov 2, 2019
@pr1ncess-z
Copy link

This is a still a bit unclear for me. In the following case:

        with(mockContext) {
            every { ccc } returns mockCcc
            every { ccr } returns mockCcr
        }

If I call clear on this mock, will the every logic be cleared as well? Do I have to reset it?

@adam-hurwitz
Copy link

My hunch is that the objects will be cleared if you call clear after the code above and you will need to reset it. You can log the objects and let us know.

@erikhuizinga
Copy link
Contributor Author

erikhuizinga commented Aug 28, 2020

Clearing resets the mock's state: it resets method/property access counts, mocked behaviour (e.g. set through every), etc. However, it doesn't unmock the mock. Unmocking is truly removing the mock from MockK's internal collection of mock instances. Unmocking also clears a mock.

After clearing a mock, you can still (re)use the mock. For example:

val mock = mockk<Any>()
every { mock.toString() } returns "foo"
assertEquals("foo", mock.toString())
verify(exactly = 1) { mock.toString() }
clearMocks(mock)
verify(exactly = 0) { mock.toString() } // Mock is reused for verification, but `toString` call count was reset

I usually instantiate mocks once per test class, i.e. in the companion object (for performance reasons), clear all mocks after every test function, and unmock all mocks after every test class.

I have published a library that does the clearing and unmocking for you: https://github.com/erikhuizinga/mockk-patterns, so you don't have to remember that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation change request fixed fixed in master
Projects
None yet
Development

No branches or pull requests

5 participants