totoromeow
totoromeow

Reputation: 2329

junit testing with mock objects: stub inner function calls

So I was trying to test ping() method and make sure that it calls connect() and disconnect(). I mocked the object foo and an object Connection. Then I did stub(mockFoo.connect()).toReturn(mockConn) hoping that then ping() should return true for me to assert. However, somehow this stubbing is not going through. I'm suspecting that maybe when connect is called internally, mockFoo didn't actually invoke connect(), hence didn't return the mock Connection, but I'm not sure.

public class foo{
    public boolean ping(){
        bool ping = false; 
        Connection conn = null;
        try{
           conn = connect();
           ping = true;
        }catch(Exception e){
        }finally{
           disconnect(conn);
        }
        return ping;
    }

    public Connection connect(){
        //some implementation
        return connect
    }

Upvotes: 0

Views: 4220

Answers (1)

bowmore
bowmore

Reputation: 11280

Usually you don't mock the unit under test itself. Mockito will use default stubbing behavior for all methods. So a call to ping() will simply return the default false, and no other methods of foo will be called.

You could do partial mocking by making a spy on foo and then stub the connect method as you have. Though I would not recommend this. Ideally you would have your dependencies on collaborators (in this case the Connection) injected. Setting up a connection, and using a connection are different responsibilities and really belong on different classes.

So more like this :

public class Foo {

    private final ConnectionProvider connectionProvider;

    private Foo(ConnectionProvider connectionProvider) {
        this.connectionProvider = connectionProvider;
    }

    public boolean ping(){
            boolean ping = false;
            Connection connection = null;
            try{
                connection = connectionProvider.getConnection();
                ping = true;
            }catch(Exception e){
                // TODO handle this exception
            }finally{
                try {
                    connection.close();
                } catch (SQLException e) {
                    // TODO handle this exception
                }
            }
            return ping;
        }

}

public interface ConnectionProvider {

    Connection getConnection();
}

@org.junit.Test
public void testConnection() throws Exception {
    ConnectionProvider mockProvider = mock(ConnectionProvider.class);
    Connection mockConnection = mock(Connection.class);
    when(mockProvider.getConnection()).thenReturn(mockConnection);

    Foo foo = new Foo(mockProvider);

    assertTrue(foo.ping());

    verify(mockConnection).close();
}

Upvotes: 5

Related Questions