0

I have this following class A. It has two functions Barney and Ted. Barney calls Ted from inside. How to mock Ted's behavior in my test class?

package MockingNestedFunction;

import java.util.ArrayList;
import java.util.List;

public class A
{
    public String Barney()
    {
        List<String> x =Ted();
        String a="";
        for(int i=0;i<x.size();i++)
        {
            a=a.concat(x.get(i));
        }
        return a;
    }

    public List<String> Ted()
    {
        List<String> x=new ArrayList<>();
        x.add("A");
        x.add("B");
        x.add("C");
        return x;
    }
}
package MockingNestedFunction;

import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.when;
import static org.testng.Assert.*;

public class ATest
{
    private A a;
    @BeforeMethod
    public void setup()
    {
        MockitoAnnotations.openMocks(this);
        a=new A();
    }

    @Test
    public void testA() throws Exception
    {
        List<String> x=new ArrayList<>();
        x.add("D");
        x.add("E");
        x.add("F");
        when(a.Ted()).thenReturn(x);
    }
}

when(a.Ted()).thenReturn(x) returns the error,when() requires an argument which has to be 'a method call on a mock'. How to effectively mock this?

  • 1
    Mostly we mock methods that are external dependencies, outside of the class and we do not want to test their behaviour. In your case, the method is in the class and I would say in order to do a proper unit test you should also test this behaviour. – PavlMits Feb 22 '21 at 08:01
  • If your class is too big to test, I'd suggest splitting it up. – tgdavies Feb 22 '21 at 08:02
  • If you decide to test them separately, you can use search function and there are plenty existing threads available, like [Use Mockito to mock some methods but not others](https://stackoverflow.com/questions/14970516/use-mockito-to-mock-some-methods-but-not-others ) – Blangero Feb 22 '21 at 08:02
  • @tgdavies I can't split it up. Is there any other way? – Christian Alderson Feb 22 '21 at 08:15

1 Answers1

0

You dont pass a method call on a mock to Mockito.when, as error message helpfully says. You are passing a method call on a object you created yourself.

If you need to stub some methods of the object under test, you are looking for a spy.

@Spy
private A a;

@BeforeMethod
public void setup() {
    MockitoAnnotations.openMocks(this);
}

As others noted in comments, stubbing some methods on object under test is a questionable practice, if you can think about restructuring the code.

On top of that: Let's keep the terminology precise. There are no nested functions in your code.

Lesiak
  • 22,088
  • 2
  • 41
  • 65