1

I Recently Started Learning About unit testing i came across Mockito Framwork i read about @Mock and @Spy when() etc..

@Mock
Service service;

@Test
void test(){
   when(service.runCode(Mock.anyString()).thenReturn("Working");
}

What my doubt in the above line is dose the runCode(String a) will get excuted OR once the Method is invoked then what i given the thenReturn() part will given by the mock

I am trying to understand mock

venkatesh
  • 13
  • 3
  • 2
    Does this answer your question? [How does mockito when() invocation work?](https://stackoverflow.com/questions/14440270/how-does-mockito-when-invocation-work) (the annotation is irrelevant here, you could have used `Mockito.mock(…)` to create the mock; no difference) – knittl May 29 '23 at 06:27

1 Answers1

0

Since you are new to unit testing, I'll write a simplified explanation of how Mocks work. Firstly, it is important to understand that dummies, fakes, mocks, spies are just different types of test objects that look like the actual object you use in production. They can be injected into the components you want to test to either verify the interaction and/or return some test data.

To understand what mockito is doing under the hood, you can initially try to write your own mocks based on a public interface:

public interface Service {
    String runCode(String arg);
}

For example, you can create a test implementation of this Service interface, that will always return the same hardcoded value, no-matter the argument passed in. This will be a Dummy:

public class DummyService implements Service {
    @Override
    public String runCode(String arg) {
        return "dummy_response";
    }
}

As a result, you'll be able to use this in your test to avoid running the actual runCode method. Assuming you have a Controller class you want to test, that internally uses this Service, the test will look like this:

@Test
void test() {
    Controller c = new Controller(new DummyService());
    var response = c.doSomething("abc");
    // assert response ...
}

As you can see, dummy objects are rather dumb. Sometimes you might want to be able to return different Strings based on the input of the method. In this case, you can create your own Mock:

public class MockedService implements Service {
    private Map<String, String> mockedData = new HashMap<>();

    public void whenRunCodeThenReturn(String arg, String mockedResponse) {
        mockedData.put(arg, mockedResponse);
    }

    @Override
    public String runCode(String arg) {
        return mockedData.get(arg);
    }
}

Now, you'll have to instantiate the MockedService and also specify some behavior, based on your test's needs:

@Test
void test() {
    MockedService mock = new MockedService();
    Controller c = new Controller(mock);
    mock.whenRunCodeThenReturn("abc", "mocked_response_for_abc");
    
    var response = c.doSomething("abc");
    // assert response ...
}

Of course, mockito is a powerful framework that offers more flexibility. It has features that allow you to define more complex conditions for the input parameters, it easily resets the mock after each test and it does not require the public interface to proxy the object.

For a more detailed explanation, about test objects such as fakes, spies and mocks, take look at this article: https://medium.com/gitconnected/the-anatomy-of-mocks-in-unit-testing-3e6a78b2b5d3

If you want to dive deeper into the framework, here is their documentation: https://site.mockito.org/

Emanuel Trandafir
  • 1,526
  • 1
  • 5
  • 13
  • A "fake" usually implements correct business logic (but a lightweight variant). The implementation which you have shown is a "dummy" (which is missing from your list of test doubles too). Good answer, the question is duplicate still. – knittl May 29 '23 at 12:04
  • I've updated the answer and changed "fake" to "dummy", thanks! Judging by the question itself (not solely by the title) I wouldn't say it's a duplicate, the link you've posted is an in-depth look at the internals of mockito, and the answers there are interesting for more experienced developers, but not really begginer-friendly. I feel that @venkatesh wanted to understand how mocks are working, in general, at a more fundamental level. – Emanuel Trandafir May 29 '23 at 12:17