Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock an exception when creating an instance of a new class using Mockito

Within a method, I have an exception being caught which I want to mock.

I know how to mock an object to throw an exception using mock.doSomething(), but I need to throw a remote exception when a class makes a new instance of itself.

transient Bicycle bike = null;

public Bicycle getBicycle() {
    if (bike == null) {
        try {
            bike = new Bicycle(this);
        } catch (RemoteException ex) {
            System.out.println("No bikes found");
        }
    }
    return bike;
}

I want to be able to mock everything in the try block, but I don't understand how you mock the creation of a new class, the following line to be specific:

bike = new Bicycle(this);

I have tried many different Mockito tests, such as:

Bicycle b = mock(Bicycle.class);
Mockito.doThrow(new RemoteException()).when(b = new Bicycle());

Although I understand this will and is not working, I want to do something similar.

I have read the Mockito docs and haven't found anything useful:

http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

like image 473
John Vasiliou Avatar asked Mar 26 '13 21:03

John Vasiliou


2 Answers

You don't generally mock constructors. You can do with tools like PowerMock, but I'd generally suggest you don't.

Currently, your code isn't actually testable, if you want to control what happens when a new Bicycle is constructed. Is constructing a Bicycle actually a complex operation? Perhaps you want a BicycleFactory, which can be passed into your class as a dependency, for example - then you could mock BicycleFactory.createBicycle or whatever you call it.

Constructors are like static methods - when you use them, you're tightly bound to the specific code you're calling; there's no clean way to inject other behaviour without approaches like PowerMock's.

like image 111
Jon Skeet Avatar answered Nov 10 '22 04:11

Jon Skeet


You can use a Mockito extension, PowerMock, in cases like this. It allows constructors to be mocked (see https://code.google.com/p/powermock/wiki/MockConstructor).

In this case, you would write something like the following test:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassUnderTest.class, Bicycle.class})
public class ConstructorMockingTest
{
    @Test
    public void getBicycle()
    {
        ClassUnderTest tested = new ClassUnderTest();
        whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException());

        Bicycle bicycle = tested.getBicycle();

        assertNull(bicycle);
    }
}

More examples can be found at: https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java

like image 4
Rogério Avatar answered Nov 10 '22 05:11

Rogério