I am new to jMockIt and so wanted to learn it. I thought of implementing a synonym servlet kata. The servlet takes a word as input and returns the synoyms of the words as a comma seperated string. The objective of the kata that I implemented was:Learning jMockIt stubbing and mocking features.Choosing between stubbing and mocking based on the situation.Implementing readable, maintainable and trustworthy unit tests.I request code reviewers to provide feedback in above mentioned areas. I am open to receive feedback about the servlet code as well. The code is below:class SynonymServlet extends HttpServlet {    public SynonymServlet(RecentCache cache, SynonymProvider provider) {        this.cache = cache;        this.provider = provider;    }    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //input processing        String word = getInputWordFromURL(request.getRequestURI());        //cache management        List<String> synonyms = cache.get(word);        if (synonyms == null) {            synonyms = provider.getSynonyms(word);            cache.put(word, synonyms);        }        //response creation        String responseString = StringUtils.join(synonyms, , );        response.getOutputStream().print(responseString);    }    private static String getInputWordFromURL(String URL) {        String[] tokenizedURL = URL.split(/);        String word = tokenizedURL[tokenizedURL.length - 1];        return word;    }    private RecentCache cache;    private SynonymProvider provider;}    interface RecentCache {        List<String> get(String word);        void put(String word, List<String> synonyms);    }    interface SynonymProvider {        List<String> getSynonyms(String word);    }    public class SynonymServletTest {        @Mocked         RecentCache cache;        @Mocked        SynonymProvider provider;        @Test        public void should_always_look_into_cache_first() throws ServletException, IOException {            //Mock            new Expectations() {                {                    cache.get(reputation);                    times = 1;                }            };            SynonymServlet servlet = new SynonymServlet(cache, provider);            servlet.doGet(getRequest(/synonyms/reputation), new MockHttpServletResponse());        }        @Test        public void should_return_from_cache_when_found() throws Exception, IOException {            //Stub            new Expectations() {                {                    cache.get(reputation);                    result = new ArrayList<String>() {{                        add(credit);                        add(reputation);                    }};                 }            };            MockHttpServletResponse response = new MockHttpServletResponse();            SynonymServlet servlet = new SynonymServlet(cache, provider);            servlet.doGet(getRequest(/synonyms/reputation), response);            assertThat(response.getContentAsString()).isEqualTo(credit, reputation);        }        @Test        public void should_get_it_from_provider_when_not_found_in_cache() throws ServletException, IOException {            //Stub            new NonStrictExpectations()             {                {                    cache.get(reputation);                    result = null;                }            };            //Mock            new Expectations() {                {                    provider.getSynonyms(reputation);                    times = 1;                }            };            SynonymServlet servlet = new SynonymServlet(cache, provider);            servlet.doGet(getRequest(/synonyms/reputation), new MockHttpServletResponse());        }        @Test        public void should_return_the_same_as_provided_by_provider() throws ServletException, IOException {            //Stub            new NonStrictExpectations() {                {                    cache.get(reputation);                    result = null;                }            };            new Expectations() {                {                    provider.getSynonyms(reputation);                    times = 1;                    result = new ArrayList<String>() {{                        add(credit);                        add(reputation);                    }};                 }            };            SynonymServlet servlet = new SynonymServlet(cache, provider);            MockHttpServletResponse response = new MockHttpServletResponse();            servlet.doGet(getRequest(/synonyms/reputation), response);            assertThat(response.getContentAsString()).isEqualTo(credit, reputation);        }        @Test        public void should_update_cache_when_not_in_cache() throws ServletException, IOException {            //Stub            new Expectations() {                {                    cache.get(reputation);                    result = null;                }            };            //Stub            new Expectations() {                {                    provider.getSynonyms(reputation);                    result = new ArrayList<String>() {{                        add(credit);                        add(reputation);                    }};                 }            };            //Mock            new Expectations() {                {                    cache.put(reputation, (List<String>) any);                    times = 1;                }            };            SynonymServlet servlet = new SynonymServlet(cache, provider);            servlet.doGet(getRequest(/synonyms/reputation), new MockHttpServletResponse());        }        private MockHttpServletRequest getRequest(String url) {            return new MockHttpServletRequestBuilder()                .withURL(url)                .build();        }    }
State and Interaction based testing using jMockIt
java;unit testing;mocks