I'm using the Mockito framework to create Mock objects in my JUnit tests. Each mock knows what methods have been called on it, so during my tests I can write
verify(myMock, atLeastOnce()).myMethod();
I am wondering if this internal mock knowledge of what it has called will persist across my tests? If it does persist, then I could be getting false positives when using the same verify
method in two tests.
A code example
@RunWith(MockitoJUnitRunner.class) public class EmrActivitiesImplTest { @Mock private MyClass myMock; @Before public void setup() { when(myMock.myMethod()).thenReturn("hello"); } @Test public void test1() { // ..some logic verify(myMock, atLeastOnce()).myMethod(); } @Test public void test2() { // ..some other logic verify(myMock, atLeastOnce()).myMethod(); } }
Mock state is persisted - test2 will pass regardless, since test1's verify method passed
Mock state is reset - test2 will fail if myMock.myMethod() isn't called
Mock objects allow you to set up test scenarios without bringing to bear large, unwieldy resources such as databases. Instead of calling a database for testing, you can simulate your database using a mock object in your unit tests.
Mock Object Drawbacks You are coupling your test to a specific implementation and behavior of the object under test. You tend to have more tests fail when they shouldn't when mocking. This makes these tests brittle.
afterEach(() => { jest. clearAllMocks(); }); to call jest. clearAllMocks to clear all mocks after each test.
JUnit creates a new instance of test class each time it runs a new test method and runs @Before
method each time it creates a new test class. You can easily test it:
@Before public void setup() { System.out.println("setup"); when(myMock.myMethod()).thenReturn("hello"); }
And MockitoJUnitRunner
will create a new MyMock
mock instance for every test method.
import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class sandbox { @Mock private MyClass myMock; @Before public void setup() { when(myMock.myMethod()).thenReturn("hello"); } @Test public void test1() { myMock.myMethod(); verify(myMock, times(1)).myMethod(); } @Test public void test2() { myMock.myMethod(); verify(myMock, times(1)).myMethod(); } }
This passes. If the state persisted then the second test would fail. If you debug it you would see that you get a new instance of the mocked object for each test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With