ken
ken

Reputation: 471

Mocking an Exception

I have some issues mocking a method (using mockito) which depending from the input parameter return a String or an exception.

The code of the unit test seems to be wrong but even after asking google I could not find a solution.

Thanks for any help

public class MyClassTest
{
    public MyClass mc;
    public ClassUnknown cu;

    @Before
    public void setUp()
    {
        mc = new MyClass();
        cu = mock(ClassUnknown.class);
        // The next two lines seems to be wrong
        when(cu.methodUnknown("hello")).thenReturn("hello there");
        when(cu.methodUnknown("???")).thenThrow(new Exception("don't know"));        
    }

    @Test
    public void testMain()
    {

        mc.mainMethod("hello");
        .....;
    }    
}

and here is the "classUnknown":

public class ClassUnknown
{
    public String methodUnknown(String s) throws Exception
    {
         // The real logic is much more complex and does some CRUD operations
        if (s.equals("Hello"))
        {
            return "Hello there";
        }
        throw new Exception("don't know");
    }
}

and the class to be tested:

public class MyClass
{

    public void mainMethod(String s)
    {
        ClassUnknown cu = new ClassUnknown();

        try
        {
            String methodUnknown = cu.methodUnknown(s);
            System.out.println(methodUnknown);
        } catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }

    }

}

Upvotes: 0

Views: 125

Answers (1)

JB Nizet
JB Nizet

Reputation: 692121

You're creating an instance of MyClass. Then you're creating a mock instance of ClassUnknown. Then you're calling mainMethod() on the instance of MyClass. This method creates another instance of ClassUnknown and uses it. So the mock instance of ClassUnknown is never used anywahere and never involved in the test.

What you need to do is pass the mock instance of ClassUnknown to the MyClass instance that you're testing (or to the method that you're testing):

public class MyClass {

    private ClassUnknown cu;

    public MyClass(ClassUnknown cu) {
        this.cu = cu;
    }

    public void mainMethod(String s) {
        try {
            String methodUnknown = cu.methodUnknown(s);
            System.out.println(methodUnknown);
        } 
        catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
}

...

@Before
public void setUp() {
    cu = mock(ClassUnknown.class);
    // The next two lines seems to be wrong
    when(cu.methodUnknown("hello")).thenReturn("hello there");
    when(cu.methodUnknown("???")).thenThrow(new Exception("don't know"));   

    mc = new MyClass(cu); // Now, the MyClass instance will use the mock.        
}

This is known as dependency injection. It's crucial to have code that is testable. MyClass depends on ClassUnknown. So MyClass doens't create its own dependency. Instead, you inject the dependency (i.e. the instance of ClassUnknown) inside MyClass.

Upvotes: 2

Related Questions