{"id":21397,"date":"2015-03-18T15:00:19","date_gmt":"2015-03-18T13:00:19","guid":{"rendered":"http:\/\/examples.javacodegeeks.com\/?p=21397"},"modified":"2022-09-27T15:14:45","modified_gmt":"2022-09-27T12:14:45","slug":"mockito-spy-example","status":"publish","type":"post","link":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/","title":{"rendered":"Mockito Spy Example"},"content":{"rendered":"<p>In this article, I am going to show you an example of Mockito Spy calls.<\/p>\n<p>There are times when we would like to use most of the original object&#8217;s behavior but mock only a portion of it. This is called spying objects, also called partial mocking. Before I start with the example, let me first brief you about my setup:<\/p>\n<ul>\n<li>I am using\u00a0<a class=\"ext-link\" title=\"\" href=\"http:\/\/maven.apache.org\/\" rel=\"external nofollow\">Maven<\/a>\u00a0\u2013 the\u00a0build tool<\/li>\n<li><a class=\"ext-link\" title=\"\" href=\"http:\/\/www.eclipse.org\/\" rel=\"external nofollow\">Eclipse <\/a>\u00a0as the\u00a0IDE, version Luna 4.4.1.<\/li>\n<li><a class=\"ext-link\" title=\"\" href=\"http:\/\/testng.org\/doc\/index.html\" rel=\"external nofollow\">TestNG <\/a>\u00a0is my\u00a0testing framework, in case you are new to TestNG, please refer\u00a0<a href=\"http:\/\/examples.javacodegeeks.com\/enterprise-java\/testng\/testng-maven-project-example\/\">TestNG Maven Project Example.<\/a><\/li>\n<li>Add <a class=\"ext-link\" title=\"\" href=\"https:\/\/maven-badges.herokuapp.com\/maven-central\/org.mockito\/mockito-core\" rel=\"external nofollow\">Mockito dependency<\/a> to our <code>pom.xml<\/code>.<\/li>\n<\/ul>\n<h2>1. Example of Mockito Spy<\/h2>\n<p>Using Mockito&#8217;s spy feature, we can mock only those methods of a real object that we want to, thus retaining the rest of the original behavior.<\/p>\n<p>The system under test is an <code>Employee<\/code>\u00a0bean which takes in <code>firstName<\/code>, <code>lastName<\/code> and <code>age<\/code>. It has the getter methods for all the attributes. It also has an additional getter method <code>getFullName()<\/code> which returns us <code>firstName<\/code> and <code>lastName<\/code> together. Internally, it relies on the respective getter methods rather than accessing attributes directly. Finally, it also has a setter method on <code>age<\/code> attribute. Why a setter method on the <code>age<\/code> attribute? The answer is, purely to prove a point regarding how the spy works and there is no design secret behind it.<\/p>\n<p>In the below example, I will show you how to set the expected behavior on a couple of <code>Employee<\/code> bean methods.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Employee:<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.mockito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Employee {\n\tprivate String firstName;\n\tprivate String lastName;\n\tprivate int age;\n\n\tpublic Employee(String firstName, String lastName, int age) {\n\t\tthis.firstName = firstName;\n\t\tthis.lastName = lastName;\n\t\tthis.age = age;\n\t\tthis.engineerAware = new Dev();\n\t}\n\n\tpublic int getAge() {\n\t\treturn age;\n\t}\n\n\tpublic String getFullName() {\n\t\treturn getFirstName() + \" \" + getLastName();\n\t}\n\n\tpublic String getLastName() {\n\t\treturn lastName;\n\t}\n\n\tpublic String getFirstName() {\n\t\treturn firstName;\n\t}\t\n\t\n\tpublic void setAge(int age) {\n\t\tthis.age = age;\n\t}\n}\n<\/pre>\n<p>Let&#8217;s analyze the test cases now.<\/p>\n<p>We create the spy object using <code>org.mockito.Mockito.spy(real object)<\/code>. In our example, we do it in the <code>@BeforeMethod<\/code>, <code>buildSpy()<\/code>. We create the <code>Employee<\/code> bean and then the spy object using <code>spy(emp)<\/code>.<\/p>\n<p>Since we have two <code>Employee<\/code> beans, one the original and the other spy, one question that naturally arises is, whether the spy object refers to the original object internally. The answer is No. Mockito creates a copy of the original object, so when methods are exercised on the spy object, the state of the original object remains unaffected. Likewise, if you interact with the real object, the object won&#8217;t be aware of those interactions.<\/p>\n<p>This is proved in <code>verifySpyEffectOnRealInstance()<\/code> where we set the age on the spied <code>Employee<\/code> bean, but the state of the real <code>Employee<\/code> bean still retains the original age. In the next two test cases, we will analyze the verification and partial mocking.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>MockitoSpyExample:<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.mockito;\n\nimport static org.mockito.Mockito.*;\nimport static org.testng.Assert.*;\n\nimport org.mockito.InOrder;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\n\npublic class MockitoSpyExample {\n\tprivate Employee spyEmp;\n\tprivate Employee emp;\n\tprivate static final String FIRST_NAME = \"Joe\";\n\tprivate static final String LAST_NAME = \"M\";\n\tprivate static final int AGE = 35;\n\t\n\t@BeforeMethod\n\tpublic void buildSpy() {\n\t\temp = new Employee(FIRST_NAME, LAST_NAME, AGE);\n\t\tspyEmp = spy(emp);\n\t}\n\t\n\t@Test\n\tpublic void verifySpyEffectOnRealInstance() {\n\t\tspyEmp.setAge(20);\n\t\tassertFalse(emp.getAge() == spyEmp.getAge());\n\t}\n\t\n\t@Test\n\tpublic void verifyEmployeeDetails() {\n\t\tSystem.out.println(\"Full name:\" + spyEmp.getFullName());\n\t\tSystem.out.println(\"Age:\" + spyEmp.getAge());\n\t\t\n\t\tInOrder inOrder = inOrder(spyEmp);\n\t\t\n\t\tSystem.out.println(\"Verify emp.getFullName() calls getFirstName() and then getLastName()\");\n\t\tinOrder.verify(spyEmp).getFirstName();\n\t\tinOrder.verify(spyEmp).getLastName();\n\t\t\n\t\tSystem.out.println(\"Verify emp.getAge() is called\");\n\t\tverify(spyEmp).getAge();\n\t\t\n\t\tassertEquals(spyEmp.getFirstName(), FIRST_NAME);\n\t\tassertEquals(spyEmp.getLastName(), LAST_NAME);\n\t\tassertEquals(spyEmp.getFullName(), FIRST_NAME + \" \" + LAST_NAME);\n\t\tassertEquals(spyEmp.getAge(), AGE);\n\t\t\n\t\tSystem.out.println(\"Verify emp.getFullName() called twice\");\n\t\tverify(spyEmp, times(2)).getFullName();\n\t}\n\t\n\t@Test\n\tpublic void spyEmployeeName() {\n\t\tfinal String I_AM = \"I am\";\n\t\tfinal String THE_SPY = \"the Spy\";\n\t\tSystem.out.println(\"Train employee to return \" + I_AM + \" when emp.getFirstName() is called\");\n\t\twhen(spyEmp.getFirstName()).thenReturn(I_AM);\n\t\tSystem.out.println(\"Full Name: \" + spyEmp.getFullName());\n\t\tassertEquals(I_AM + \" M\", spyEmp.getFullName());\n\t\t\n\t\tSystem.out.println(\"Train employee to return \" + THE_SPY + \" when emp.getLastName() is called\");\n\t\twhen(spyEmp.getLastName()).thenReturn(THE_SPY);\n\t\tSystem.out.println(\"Full Name: \" + spyEmp.getFullName());\n\t\tassertEquals(I_AM + \" \" + THE_SPY, spyEmp.getFullName());\n\t}\t\n}\n<\/pre>\n<p>In <code>verifyEmployeeDetails()<\/code>, we call <code>getFullName()<\/code> on the spied object. We know internally it calls <code>getFirstName()<\/code> and <code>getLastName()<\/code>. We can verify this and the order in which they are called using <code>InOrder<\/code>. The spy object is encapsulated in <code>InOrder<\/code> object and then we verify the order of\u00a0interaction of <code>getFirstName()<\/code> and <code>getLastName().<\/code><div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>We can also verify the method invocations by their count. For example, <code>verify(spyEmp, times(2)).getFullName()<\/code>.<\/p>\n<p>In <code>spyEmployeeName()<\/code>, we do the partial mocking. We train the spied <code>Employee<\/code> bean to return &#8220;I am&#8221; when <code>getFirstName()<\/code> is called. Since <code>getFullName()<\/code> calls <code>getFirstName()<\/code> and <code>getLastName()<\/code>, we can see the change in its full name when <code>getFullName()<\/code> is called. It returns &#8220;I am M&#8221;.<\/p>\n<p>Next, we train the <code>getLastName()<\/code> to return the spy. This again reflects in the full name and returns &#8220;I am the spy&#8221;.<\/p>\n<p><em><span style=\"text-decoration: underline;\">Output:<\/span><\/em><\/p>\n<pre class=\"brush:bash\">PASSED: verifySpyEffectOnRealInstance\n\nTrain employee to return I am when emp.getFirstName() is called\nFull Name: I am M\nTrain employee to return the Spy when emp.getLastName() is called\nFull Name: I am the Spy\nPASSED: spyEmployeeName\n\nFull name:Joe M\nAge:35\nVerify emp.getFullName() calls getFirstName() and then getLastName()\nVerify emp.getAge() is called\nVerify emp.getFullName() called twice\nPASSED: verifyEmployeeDetails\n<\/pre>\n<h2>2. Spying on Interface<\/h2>\n<p>In the below example, I show you that one can even spy on an anonymous object. In the test case <code>spyOnInterface<\/code>, we create a spy object on <code>EngineerAware<\/code> implementation called <code>Dev<\/code>. We can see it returns us the expected enum <code>Engineer.DEV<\/code>. Next, we train the spy object to return <code>Engineer.QA,<\/code> which it does.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>EngineerAware:<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.mockito;\n\npublic interface EngineerAware {\n\tEngineer getDesignation();\n\t\n\tenum Engineer {\n\t\tDEV,QA\n\t}\n}\n<\/pre>\n<p><span style=\"text-decoration: underline;\"><em>SpyOnInterfaceExample:<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.mockito;\n\nimport org.testng.annotations.Test;\n\nimport com.javacodegeeks.mockito.EngineerAware.Engineer;\n\nimport static org.mockito.Mockito.*;\nimport static org.testng.Assert.*;\n\npublic class SpyOnInterfaceExample {\n\t@Test\n\tpublic void spyOnInterface() {\n\t\tEngineerAware engineerAware = spy(new Dev());\n\t\tassertEquals(Engineer.DEV, engineerAware.getDesignation());\n\t\twhen(engineerAware.getDesignation()).thenReturn(Engineer.QA);\n\t\tassertEquals(Engineer.QA, engineerAware.getDesignation());\n\t}\t\n\tprivate class Dev implements EngineerAware {\n\t\t@Override\n\t\tpublic Engineer getDesignation() {\n\t\t\treturn Engineer.DEV;\n\t\t}\t\t\n\t}\n}\n<\/pre>\n<h2>3. Stubbing a final method in a Spy Object<\/h2>\n<p>In this Mockito spy example, I demonstrate that we can&#8217;t train a final method. Method <code>moveTo()<\/code>, updates employee&#8217;s designation. We also have another method, <code>finalMoveTo()<\/code> which does the same as <code>moveTo ()<\/code> but is a final method.<br \/>\nIn our test cases, we will try to train the final method and see how it behaves.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Employee:<\/em><\/span><\/p>\n<pre class=\"brush:java; highlight:[40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55]\">package com.javacodegeeks.mockito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Employee {\n\tprivate String firstName;\n\tprivate String lastName;\n\tprivate int age;\n\tprivate EngineerAware engineerAware;\n\tprivate List skills;\n\n\tpublic Employee(String firstName, String lastName, int age) {\n\t\tthis.firstName = firstName;\n\t\tthis.lastName = lastName;\n\t\tthis.age = age;\n\t\tthis.engineerAware = new Dev();\n\t}\n\n\tpublic int getAge() {\n\t\treturn age;\n\t}\n\n\tpublic String getFullName() {\n\t\treturn getFirstName() + \" \" + getLastName();\n\t}\n\n\tpublic String getLastName() {\n\t\treturn lastName;\n\t}\n\n\tpublic String getFirstName() {\n\t\treturn firstName;\n\t}\t\n\t\n\tpublic void setAge(int age) {\n\t\tthis.age = age;\n\t}\n\n\tpublic final void finalMoveTo(EngineerAware engineerAware) {\n\t\tSystem.out.println(\"Employee moves from \" + this.engineerAware.getDesignation() + \" to \" + engineerAware.getDesignation());\n\t\tthis.engineerAware = engineerAware;\n\t}\n\t\n\tpublic void moveTo(EngineerAware engineerAware) {\n\t\tSystem.out.println(\"Employee moves from \" + this.engineerAware.getDesignation() + \" to \" + engineerAware.getDesignation());\n\t\tthis.engineerAware = engineerAware;\n\t}\n\t\n\tprivate class Dev implements EngineerAware {\n\t\t@Override\n\t\tpublic Engineer getDesignation() {\n\t\t\treturn Engineer.DEV;\n\t\t}\t\t\n\t}\n}\n<\/pre>\n<ol>\n<li>In the test case, <code>stubNonFinalMoveTo()<\/code>, we train <code>moveTo()<\/code> method to throw a <code>RuntimeException<\/code>.<\/li>\n<li>In <code>stubFinalMoveTo()<\/code>, we do the same with the final method <code>finalMoveTo()<\/code>.<\/li>\n<\/ol>\n<p>Since <code>finalMoveTo()<\/code>\u00a0is final, Mockito fails to train\u00a0it and instead simply invokes the real object&#8217;s method, which is why it fails to throw <code>RuntimeException<\/code>.[ulp id=&#8217;GhnY46zldrhgoeym&#8217;]<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StubOnFinalMethod:<\/em><\/span><\/p>\n<pre class=\"brush:java\">package com.javacodegeeks.mockito;\n\nimport static org.mockito.Mockito.*;\n\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\n\npublic class StubOnFinalMethod {\n\tprivate Employee emp;\n\tprivate static final String FIRST_NAME = \"Joe\";\n\tprivate static final String LAST_NAME = \"M\";\n\tprivate static final int AGE = 35;\n\tQA qa = new QA();\n\t\n\t@BeforeMethod\n\tpublic void buildSpy() {\n\t\temp = spy(new Employee(FIRST_NAME, LAST_NAME, AGE));\n\t}\n\t\n\t@Test(expectedExceptions=RuntimeException.class)\n\tpublic void stubNonFinalMoveTo() {\n\t\tdoThrow(new RuntimeException(\"Can't move to a different department\")).when(emp).moveTo(qa);\n\t\temp.moveTo(qa);\n\t}\n\t\n\t@Test(expectedExceptions=RuntimeException.class)\n\tpublic void stubFinalMoveTo() {\n\t\tdoThrow(new RuntimeException(\"Can't move to a different department\")).when(emp).finalMoveTo(qa);\n\t\temp.finalMoveTo(qa);\n\t}\n\t\n\tprivate class QA implements EngineerAware {\n\t\t@Override\n\t\tpublic Engineer getDesignation() {\n\t\t\treturn Engineer.QA;\n\t\t}\t\t\n\t}\n}\n<\/pre>\n<p><span style=\"text-decoration: underline;\"><em>Output:<\/em><\/span><\/p>\n<pre class=\"brush:bash\">Employee moves from DEV to QA\nEmployee moves from QA to QA\nFAILED: stubFinalMoveTo\norg.testng.TestException: \nExpected exception java.lang.RuntimeException but got org.testng.TestException:\n\nPASSED: stubNonFinalMoveTo\n<\/pre>\n<h2>4. Using doReturn(Object) for stubbing spies<\/h2>\n<p>By using Mockito Spy, there are times when calling when(Object) for stubbing might be inappropriate. In such situations, we should consider using <code>doReturn<\/code> for stubbing.<br \/>\nIn our <code>Employee<\/code> bean, I have added a couple of new methods to help us capture three employee skills. We access the skill using <code>getSkill(index)<\/code> which returns us the skill based on the index passed in.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Employee:<\/em><\/span><\/p>\n<pre class=\"brush:java; highlight:[57,58,59,60,61,62,63,64,65,66,67,68]\">package com.javacodegeeks.mockito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Employee {\n\tprivate String firstName;\n\tprivate String lastName;\n\tprivate int age;\n\tprivate EngineerAware engineerAware;\n\tprivate List skills;\n\n\tpublic Employee(String firstName, String lastName, int age) {\n\t\tthis.firstName = firstName;\n\t\tthis.lastName = lastName;\n\t\tthis.age = age;\n\t\tthis.engineerAware = new Dev();\n\t}\n\n\tpublic int getAge() {\n\t\treturn age;\n\t}\n\n\tpublic String getFullName() {\n\t\treturn getFirstName() + \" \" + getLastName();\n\t}\n\n\tpublic String getLastName() {\n\t\treturn lastName;\n\t}\n\n\tpublic String getFirstName() {\n\t\treturn firstName;\n\t}\t\n\t\n\tpublic void setAge(int age) {\n\t\tthis.age = age;\n\t}\n\n\tpublic final void finalMoveTo(EngineerAware engineerAware) {\n\t\tSystem.out.println(\"Employee moves from \" + this.engineerAware.getDesignation() + \" to \" + engineerAware.getDesignation());\n\t\tthis.engineerAware = engineerAware;\n\t}\n\t\n\tpublic void moveTo(EngineerAware engineerAware) {\n\t\tSystem.out.println(\"Employee moves from \" + this.engineerAware.getDesignation() + \" to \" + engineerAware.getDesignation());\n\t\tthis.engineerAware = engineerAware;\n\t}\n\t\n\tprivate class Dev implements EngineerAware {\n\t\t@Override\n\t\tpublic Engineer getDesignation() {\n\t\t\treturn Engineer.DEV;\n\t\t}\t\t\n\t}\n\t\n\tpublic String getSkill(int index) {\n\t\treturn skills.get(index);\n\t}\n\t\n\tpublic void addSkill(String skill1, String skill2, String skill3) {\n\t\tif (skills == null) {\n\t\t\tskills = new ArrayList(3);\n\t\t}\n\t\tskills.add(0, skill1);\n\t\tskills.add(1, skill2);\n\t\tskills.add(2, skill3);\n\t}\n}\n<\/pre>\n<p>Suppose we want to train our spy object <code>Employee<\/code> bean to return us &#8220;SPY&#8221; when <code>getSkill(0)<\/code> is called, using <code>when()<\/code> API like below will throw <code>NullPointerException<\/code>. Note that <code>spyEmp.getSkill(0)<\/code> calls on the original method and since the <code>List<\/code> object is not yet initialized, it throws <code>NullPointerException<\/code>.<\/p>\n<pre class=\"brush:java\">when(spyEmp.getSkill(0)).thenReturn(\"SPY\");\n<\/pre>\n<p>This can be done differently using <code>doReturn()<\/code> for stubbing. For example, in the below style, we get around the <code>NullPointerException<\/code>.<\/p>\n<pre class=\"brush:java\">doReturn(\"SPY\").when(spyEmp).getSkill(0);\n<\/pre>\n<p>Both the cases are demonstrated in <code>spySkillUsingWhenThenReturn<\/code> and <code>spySkillUsingDoWhen<\/code>.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>MockitoSpyExample:<\/em><\/span><\/p>\n<pre class=\"brush:java; highlight:[67,68,69,70,71,72,73,74,75,76,77]\">package com.javacodegeeks.mockito;\n\nimport static org.mockito.Mockito.*;\nimport static org.testng.Assert.*;\n\nimport org.mockito.InOrder;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\n\npublic class MockitoSpyExample {\n\tprivate Employee spyEmp;\n\tprivate Employee emp;\n\tprivate static final String FIRST_NAME = \"Joe\";\n\tprivate static final String LAST_NAME = \"M\";\n\tprivate static final int AGE = 35;\n\t\n\t@BeforeMethod\n\tpublic void buildSpy() {\n\t\temp = new Employee(FIRST_NAME, LAST_NAME, AGE);\n\t\tspyEmp = spy(emp);\n\t}\n\t\n\t@Test\n\tpublic void verifySpyEffectOnRealInstance() {\n\t\tspyEmp.setAge(20);\n\t\tassertFalse(emp.getAge() == spyEmp.getAge());\n\t}\n\t\n\t@Test\n\tpublic void verifyEmployeeDetails() {\n\t\tSystem.out.println(\"Full name:\" + spyEmp.getFullName());\n\t\tSystem.out.println(\"Age:\" + spyEmp.getAge());\n\t\t\n\t\tInOrder inOrder = inOrder(spyEmp);\n\t\t\n\t\tSystem.out.println(\"Verify emp.getFullName() calls getFirstName() and then getLastName()\");\n\t\tinOrder.verify(spyEmp).getFirstName();\n\t\tinOrder.verify(spyEmp).getLastName();\n\t\t\n\t\tSystem.out.println(\"Verify emp.getAge() is called\");\n\t\tverify(spyEmp).getAge();\n\t\t\n\t\tassertEquals(spyEmp.getFirstName(), FIRST_NAME);\n\t\tassertEquals(spyEmp.getLastName(), LAST_NAME);\n\t\tassertEquals(spyEmp.getFullName(), FIRST_NAME + \" \" + LAST_NAME);\n\t\tassertEquals(spyEmp.getAge(), AGE);\n\t\t\n\t\tSystem.out.println(\"Verify emp.getFullName() called twice\");\n\t\tverify(spyEmp, times(2)).getFullName();\n\t}\n\t\n\t@Test\n\tpublic void spyEmployeeName() {\n\t\tfinal String I_AM = \"I am\";\n\t\tfinal String THE_SPY = \"the Spy\";\n\t\tSystem.out.println(\"Train employee to return \" + I_AM + \" when emp.getFirstName() is called\");\n\t\twhen(spyEmp.getFirstName()).thenReturn(I_AM);\n\t\tSystem.out.println(\"Full Name: \" + spyEmp.getFullName());\n\t\tassertEquals(I_AM + \" M\", spyEmp.getFullName());\n\t\t\n\t\tSystem.out.println(\"Train employee to return \" + THE_SPY + \" when emp.getLastName() is called\");\n\t\twhen(spyEmp.getLastName()).thenReturn(THE_SPY);\n\t\tSystem.out.println(\"Full Name: \" + spyEmp.getFullName());\n\t\tassertEquals(I_AM + \" \" + THE_SPY, spyEmp.getFullName());\n\t}\n\t\n\t@Test\n\tpublic void spySkillUsingWhenThenReturn() {\n\t\twhen(spyEmp.getSkill(0)).thenReturn(\"SPY\");\n\t\tassertEquals(\"SPY\", spyEmp.getSkill(0));\n\t}\n\t\n\t@Test\n\tpublic void spySkillUsingDoWhen() {\n\t\tdoReturn(\"SPY\").when(spyEmp).getSkill(0);\n\t\tassertEquals(\"SPY\", spyEmp.getSkill(0));\n\t}\n}\n<\/pre>\n<p><span style=\"text-decoration: underline;\"><em>Output:<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FAILED: spySkillUsingWhenThenReturn\njava.lang.NullPointerException\n\tat com.javacodegeeks.mockito.Employee.getSkill(Employee.java:54)\n\nPASSED: spySkillUsingDoWhen\n<\/pre>\n<h2>5. Download the Eclipse Project<\/h2>\n<p>This was an example of <a href=\"https:\/\/examples.javacodegeeks.com\/how-to-use-spies-in-mockito\/\">Mockito Spy<\/a>.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <a href=\"http:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockitoSpy.zip\"><strong>mockitoSpy.zip<\/strong><\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original object&#8217;s behavior but mock only a portion of it. This is called spying objects, also called partial mocking. Before I start with the example, let me first &hellip;<\/p>\n","protected":false},"author":38,"featured_media":21338,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[923],"tags":[],"class_list":["post-21397","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mockito"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Mockito Spy Example - Examples Java Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Mockito Spy Example - Examples Java Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\" \/>\n<meta property=\"og:site_name\" content=\"Examples Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-18T13:00:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-09-27T12:14:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Ram Mokkapaty\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ram Mokkapaty\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\"},\"author\":{\"name\":\"Ram Mokkapaty\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/7b1823eb5bd673bd375f8bee33b70cd8\"},\"headline\":\"Mockito Spy Example\",\"datePublished\":\"2015-03-18T13:00:19+00:00\",\"dateModified\":\"2022-09-27T12:14:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\"},\"wordCount\":814,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg\",\"articleSection\":[\"Mockito\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\",\"name\":\"Mockito Spy Example - Examples Java Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg\",\"datePublished\":\"2015-03-18T13:00:19+00:00\",\"dateModified\":\"2022-09-27T12:14:45+00:00\",\"description\":\"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...\",\"breadcrumb\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/examples.javacodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java Development\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Core Java\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/core-java\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Mockito\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/java-development\/core-java\/mockito\/\"},{\"@type\":\"ListItem\",\"position\":5,\"name\":\"Mockito Spy Example\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Examples and Code Snippets\",\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/javacodegeeks\",\"https:\/\/x.com\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/7b1823eb5bd673bd375f8bee33b70cd8\",\"name\":\"Ram Mokkapaty\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2014\/12\/Ram-Mokkapaty-96x96.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2014\/12\/Ram-Mokkapaty-96x96.jpg\",\"caption\":\"Ram Mokkapaty\"},\"description\":\"Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.\",\"sameAs\":[\"http:\/\/www.javacodegeeks.com\/\",\"https:\/\/in.linkedin.com\/pub\/ram-satish-mokkapaty\/18\/123\/52b\"],\"url\":\"https:\/\/examples.javacodegeeks.com\/author\/ram-mokkapaty\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Mockito Spy Example - Examples Java Code Geeks - 2026","description":"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/","og_locale":"en_US","og_type":"article","og_title":"Mockito Spy Example - Examples Java Code Geeks - 2026","og_description":"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...","og_url":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/","og_site_name":"Examples Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-03-18T13:00:19+00:00","article_modified_time":"2022-09-27T12:14:45+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg","type":"image\/jpeg"}],"author":"Ram Mokkapaty","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Ram Mokkapaty","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#article","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/"},"author":{"name":"Ram Mokkapaty","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/7b1823eb5bd673bd375f8bee33b70cd8"},"headline":"Mockito Spy Example","datePublished":"2015-03-18T13:00:19+00:00","dateModified":"2022-09-27T12:14:45+00:00","mainEntityOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/"},"wordCount":814,"commentCount":1,"publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg","articleSection":["Mockito"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/","url":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/","name":"Mockito Spy Example - Examples Java Code Geeks - 2026","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg","datePublished":"2015-03-18T13:00:19+00:00","dateModified":"2022-09-27T12:14:45+00:00","description":"In this article, I am going to show you an example of Mockito Spy calls. There are times when we would like to use most of the original...","breadcrumb":{"@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#primaryimage","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/03\/mockito-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/examples.javacodegeeks.com\/java-development\/core-java\/mockito\/mockito-spy-example\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/examples.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java Development","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/"},{"@type":"ListItem","position":3,"name":"Core Java","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/core-java\/"},{"@type":"ListItem","position":4,"name":"Mockito","item":"https:\/\/examples.javacodegeeks.com\/category\/java-development\/core-java\/mockito\/"},{"@type":"ListItem","position":5,"name":"Mockito Spy Example"}]},{"@type":"WebSite","@id":"https:\/\/examples.javacodegeeks.com\/#website","url":"https:\/\/examples.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Examples and Code Snippets","publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/examples.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/examples.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/7b1823eb5bd673bd375f8bee33b70cd8","name":"Ram Mokkapaty","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2014\/12\/Ram-Mokkapaty-96x96.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2014\/12\/Ram-Mokkapaty-96x96.jpg","caption":"Ram Mokkapaty"},"description":"Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.","sameAs":["http:\/\/www.javacodegeeks.com\/","https:\/\/in.linkedin.com\/pub\/ram-satish-mokkapaty\/18\/123\/52b"],"url":"https:\/\/examples.javacodegeeks.com\/author\/ram-mokkapaty\/"}]}},"_links":{"self":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/21397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/users\/38"}],"replies":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=21397"}],"version-history":[{"count":0,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/21397\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media\/21338"}],"wp:attachment":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=21397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=21397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=21397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}