4

Im struggeling to learn Mockito to unittest a application. Below is a example of the method im currently trying to test

public boolean validateFormula(String formula) { boolean validFormula = true; double result = 0; try { result = methodThatCalculatAFormula(formula, 10, 10); } catch (Exception e) { validFormula = false; } if (result == 0) validFormula = false; return validFormula; } 

This method calls another method in the same class, methodThatCalculatAFormula, which I do not want to call when i unittest validateFormula.

To test this, I would like to see how this method behaves depending on what methodThatCalculatAFormula returns. Since it returns false when result is 0, and returns valid if it's any number but 0 I would like to simulate these returnvalues without running the actual methodThatCalculatAFormula method.

I have written the following:

public class FormlaServiceImplTest { @Mock FormulaService formulaService; @Before public void beforeTest() { MockitoAnnotations.initMocks(this); } @Test public void testValidateFormula() { `//Valid since methodThatCalculatAFormula returns 3` when(formulaService.methodThatCalculatAFormula(anyString(),anyDouble(),anyDouble(),anyBoolean())).thenReturn((double)3); assertTrue(formulaService.validateFormula("Valid")); //Not valid since methodThatCalculatAFormula returns 0 when(formulaService.methodThatCalculatAFormula(anyString(),anyDouble(),anyDouble(),anyBoolean())).thenReturn((double)0); assertFalse(formulaService.validateFormula("Not Valid")); } 

However when I run the above code my assertTrue is false. Im guessing i've done something wrong in my mock setup. How would I test the above method by simulating the return value of methodThatCalculatAFormula without actually calling it.

2 Answers 2

4

What you're trying to do is not a mock but a spy (partial mock). You don't want to mock an object, but just one method.

This works:

public class FormulaService { public boolean validateFormula(String formula) { boolean validFormula = true; double result = 0; try { result = methodThatCalculatAFormula(formula, 10, 10); } catch (Exception e) { validFormula = false; } if (result == 0) validFormula = false; return validFormula; } public double methodThatCalculatAFormula(String formula, int i, int j){ return 0; } } 

and

public class FormulaServiceImplTest { FormulaService formulaService; @Test public void testValidateFormula() { formulaService = spy(new FormulaService()); // Valid since methodThatCalculatAFormula returns 3` doReturn((double) 3).when( formulaService).methodThatCalculatAFormula(anyString(), anyInt(), anyInt()); assertTrue(formulaService.validateFormula("Valid")); // Not valid since methodThatCalculatAFormula returns 0 doReturn((double)0).when( formulaService).methodThatCalculatAFormula(anyString(), anyInt(), anyInt()); assertFalse(formulaService.validateFormula("Not Valid")); } } 

But you should not use spy. You should refactor class into two, so that you can test one against a mock of the other.

Sign up to request clarification or add additional context in comments.

3 Comments

The spy command worked fine. As I understand, it only mocks the specified methods which makes it testable even tho it's a mock.
Yes, and make sure to use the syntax doReturn(result).when(spy).method() and not when(spy.method()).doReturn(result). The latter one won't work, as it will call the original method before defining the mock method
Yeah I noticed that since i got a UnfinishedStubbException which I googled and found the answer too.
0

You can't test code in Mocked classes. If you just Mock it, all of the methods are stubs.

You have to Spy it instead. Read the Mockito documentation on how to use Spy.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.