Mockito Stubbing With Throwables

0

There are times when we want to stub the exceptions. Mockito provides an API to raise errors during testing. It provides methods thenThrow(Throwable) and doThrow(Throwable), so one can stub the mock to throw an exception when the stubbed method is invoked. In this article, we will look into stubbing with exceptions.

Mockito is an open source mock unit testing framework for Java. In this article, we will look into some of the stubbing examples using answer callback.

Below are my setup details:

System Under Test

All our stubbing examples follow a simple model. Our model consists of interface Tree and class Seed. We know when we plant a seed, it eventually grows into a tree. We have included this in Tree interface.

Tree:

package com.javarticles.mokcito;

public interface Tree {
    Tree grow(Seed seed, boolean isRotten) throws RottenSeedException;
    
    String getName();
    
    void pluckFruits();
}

Seed:

package com.javarticles.mokcito;

public class Seed {
    private String name;
    private boolean isRotten;
    private Tree tree;
    
    public Seed(String name) {
        this.name = name;
    }
    
    public Seed(Tree tree) {
        this.tree = tree;
    }
    
    public Tree getTree() {
        return tree;
    }

    public Tree grow() throws RottenSeedException {
        if (tree != null) {
            return tree.grow(this, isRotten);
        }  
        return null;
    }
      
    public String getName() {
        return name;
    }
    
    public String toString() {
        String nameOfThreTree = (tree == null)  ? name : tree.getName();
        return "Seed(" + nameOfThreTree + ")";
    }

    public boolean isRotten() {
        return isRotten;
    }

    public void setRotten(boolean isRotten) {
        this.isRotten = isRotten;
    }

    public void setTree(Tree tree) {
        this.tree = tree;
    }        
    
}

RottenSeedException:

package com.javarticles.mokcito;

public class RottenSeedException extends Exception {

}

NoFruitsFoundException:

package com.javarticles.mokcito;

public class NoFruitsFoundException extends RuntimeException {

}

Stub with Checked Exception

We will stub the mock object tree to throw an exception when method tree.grow(seed, true) is called. When the seed is rotten, grow() will fail with RottenSeedException.

when(tree.grow(seed, true)).thenThrow(new RottenSeedException());

StubbingWithThrowabeTests:

package com.javarticles.mockito;

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

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

import com.javarticles.mokcito.NoFruitsFoundException;
import com.javarticles.mokcito.RottenSeedException;
import com.javarticles.mokcito.Seed;
import com.javarticles.mokcito.Tree;

public class StubbingWithThrowabeTests {
    public Tree tree;
    
    @BeforeMethod
    public void createStub() {
        tree = mock(Tree.class);
    }
    
    @Test
    public void seedIsRotten() throws Exception {
        Seed seed = new Seed(tree);        
        when(tree.grow(seed, true)).thenThrow(new RottenSeedException());
        seed.grow();
        seed.setRotten(true);
        try {
            seed.grow();
            fail("Allows to grow a rotten seed");
        } catch (RottenSeedException e) {            
        }
    }
}

Stub Void Method

Since Void methods don’t return any value so when(mock.methodCall()) pattern won’t work, in order to throw exception from a void method we will use the below pattern.
Start with doThrow(Throwable) and then call on when(mock) and then void method to be invoked.

doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();

StubbingWithThrowabeTests:

package com.javarticles.mockito;

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

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

import com.javarticles.mokcito.NoFruitsFoundException;
import com.javarticles.mokcito.RottenSeedException;
import com.javarticles.mokcito.Seed;
import com.javarticles.mokcito.Tree;

public class StubbingWithThrowabeTests {
    public Tree tree;
    
    @BeforeMethod
    public void createStub() {
        tree = mock(Tree.class);
    }
    
    @Test
    public void seedIsRotten() throws Exception {
        Seed seed = new Seed(tree);        
        when(tree.grow(seed, true)).thenThrow(new RottenSeedException());
        seed.grow();
        seed.setRotten(true);
        try {
            seed.grow();
            fail("Allows to grow a rotten seed");
        } catch (RottenSeedException e) {            
        }
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowable() {
        doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();
        tree.pluckFruits();
    }
}

Stub With Throwable Class

doThrow() can also be called on the Throwable.class.

doThrow(NoFruitsFoundException.class).when(tree).pluckFruits();

StubbingWithThrowabeTests:

package com.javarticles.mockito;

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

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

import com.javarticles.mokcito.NoFruitsFoundException;
import com.javarticles.mokcito.RottenSeedException;
import com.javarticles.mokcito.Seed;
import com.javarticles.mokcito.Tree;

public class StubbingWithThrowabeTests {
    public Tree tree;
    
    @BeforeMethod
    public void createStub() {
        tree = mock(Tree.class);
    }
    
    @Test
    public void seedIsRotten() throws Exception {
        Seed seed = new Seed(tree);        
        when(tree.grow(seed, true)).thenThrow(new RottenSeedException());
        seed.grow();
        seed.setRotten(true);
        try {
            seed.grow();
            fail("Allows to grow a rotten seed");
        } catch (RottenSeedException e) {            
        }
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowable() {
        doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowableClass() {
        doThrow(NoFruitsFoundException.class).when(tree).pluckFruits();
        tree.pluckFruits();
    }
}

Stub With Error

In this example, we stub to throw Error.

StubbingWithThrowabeTests:

package com.javarticles.mockito;

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

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

import com.javarticles.mokcito.NoFruitsFoundException;
import com.javarticles.mokcito.RottenSeedException;
import com.javarticles.mokcito.Seed;
import com.javarticles.mokcito.Tree;

public class StubbingWithThrowabeTests {
    public Tree tree;
    
    @BeforeMethod
    public void createStub() {
        tree = mock(Tree.class);
    }
    
    @Test
    public void seedIsRotten() throws Exception {
        Seed seed = new Seed(tree);        
        when(tree.grow(seed, true)).thenThrow(new RottenSeedException());
        seed.grow();
        seed.setRotten(true);
        try {
            seed.grow();
            fail("Allows to grow a rotten seed");
        } catch (RottenSeedException e) {            
        }
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowable() {
        doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowableClass() {
        doThrow(NoFruitsFoundException.class).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=Error.class)
    public void stubWithError() {
        doThrow(Error.class).when(tree).pluckFruits();
        tree.pluckFruits();
    }
}

Last Stubbing Of Void Method Overrides the Previous Ones

The second stubbing overrides the first one and thus the last one is given importance so NoFruitsFoundException is thrown when tree.pluckFruits().

doThrow(new RuntimeException()).when(tree).pluckFruits();
doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();

StubbingWithThrowabeTests:

package com.javarticles.mockito;

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

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

import com.javarticles.mokcito.NoFruitsFoundException;
import com.javarticles.mokcito.RottenSeedException;
import com.javarticles.mokcito.Seed;
import com.javarticles.mokcito.Tree;

public class StubbingWithThrowabeTests {
    public Tree tree;
    
    @BeforeMethod
    public void createStub() {
        tree = mock(Tree.class);
    }
    
    @Test
    public void seedIsRotten() throws Exception {
        Seed seed = new Seed(tree);        
        when(tree.grow(seed, true)).thenThrow(new RottenSeedException());
        seed.grow();
        seed.setRotten(true);
        try {
            seed.grow();
            fail("Allows to grow a rotten seed");
        } catch (RottenSeedException e) {            
        }
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowable() {
        doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowableClass() {
        doThrow(NoFruitsFoundException.class).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=Error.class)
    public void stubWithError() {
        doThrow(Error.class).when(tree).pluckFruits();
        tree.pluckFruits();
    }
    
    @Test(expectedExceptions=NoFruitsFoundException.class)
    public void stubWithThrowableMultipleTimesLastOneOverrides() {
        doThrow(new RuntimeException()).when(tree).pluckFruits();
        doThrow(new NoFruitsFoundException()).when(tree).pluckFruits();
        tree.pluckFruits();
    }
}

Download the source code

This was an example about Mockito Stubbing With Throwables.

mockitoStubbingWithThrowables.zip
Share.

Comments are closed.