How to use EasyMock's expect method when unit testing

I recently blogged about getting started with EasyMock - a simple framework for taking the pain out of creating and using mock objects when unit testing your java code.

In the example I showed that we were expecting the next() method to be called and we wanted the mock ResultSet to return false:

expect(mockResultSet.next()).andReturn(false);
What I didn't explain was that you use the expect() method when you are expecting the mock to return a value. If the method doesn't return a value (such as ResultSet.close()) then there is no need to wrap it in an expect() method call:
mockResultSet.close();
Remember: any methods that you call on your mock prior to the replay() method call are setting up it's expectations not actually calling the methods. After the replay() method is called the mock is in 'live' mode, recording activity and returning any predefined values when it's methods are called.

So here is the same example with the additional expected close() method call:
public class ResultReporterTest {

@Test
public void parseReturnsFalseIfPassedAnEmptyResultSet() throws SQLException {

ResultSet mockResultSet = createMock(ResultSet.class); // 1

expect(mockResultSet.next()).andReturn(false); // 2
mockResultSet.close();

replay(mockResultSet); // 3

ResultReporter reporter = new ResultReporter();
assertFalse(reporter.parse(mockResultSet));

verify(mockResultSet); // 4
}
}
Technorati Tags: , , , ,

Getting started with Java Mock Objects using EasyMock

If you are familiar with unit testing and test driven development then you are most probably aware of Mock Objects.

The EasyMock website states that:

A Mock Object is a test-oriented replacement for a collaborator. It is configured to simulate the object that it replaces in a simple way. In contrast to a stub, a Mock Object also verifies whether it is used as expected.
Mock Objects were introduced at XP 2000 by Tim Mackinnon, Steve Freeman and Philip Craig with the Endo-Testing: Unit Testing with Mock Objects paper.

So how do you use them? Basically you want to test some code that depends on a number of other objects. Some of these objects might have unwanted side effects like talking to a database, or accessing an external URL.

Rather than passing in the real implementation (with the above side effects) you would pass in a mock or stub instead. The mock can be pre-wired to expect a number of calls to it's methods from the code under test and will record these calls for verification later. Typically these mock objects were written by hand and so have fairly simple implementations, EasyMock removes that hard work by using Java's proxy mechanism to do most of the heavy lifting for you.

EasyMock has four stages:
  1. createMock - Create the mock based on an existing interface or class
  2. expect - Record the method calls that you expect your code under test to call indicating what you expect to be returned, if valid
  3. replay - Set the mock into 'playback' mode which switches the mock into 'real' mode and starts recording method calls and returning objects as set up in the previous stage
  4. verify - make sure that the right methods were called in the right order
Note: The standard download of EasyMock out of the box only supports creating mocks based on interfaces, if you also want to make mocks based on classes then you also need to download EasyMock Class Extensions. Then you don't use:
import static org.easymock.EasyMock.*;
you use this instead:
import static org.easymock.classextension.EasyMock.*;
And now for an example...

Let's assume we are developing a reporting object which manipulates the output of a database query. It's going to parse through a JDBC ResultSet object and do something with the results. We want the parse() method to return false if there are no rows within the ResultSet:
class ResultReporter {

boolean parse(ResultSet results) throws SQLException {
if (!results.next()) {
return false;
}

// do something with the results

return true;
}
}
So how do we test this method? We could run an SQL query against a database and then pass the ResultSet in but that would be slow and rely on external resources. We could handcode a mock version - but have you seen how many methods the ResultSet interface has?!? Or we could use EasyMock to help us out:
public class ResultReporterTest {

@Test
public void parseReturnsFalseIfPassedAnEmptyResultSet() throws SQLException {

ResultSet mockResultSet = createMock(ResultSet.class); // 1

expect(mockResultSet.next()).andReturn(false); // 2

replay(mockResultSet); // 3

ResultReporter reporter = new ResultReporter();
assertFalse(reporter.parse(mockResultSet));

verify(mockResultSet); // 4
}
}

Technorati Tags: , , , , , , , , ,

How to enable Line In Pass Through to your speakers with Realtek Audio on Windows XP

If you are having problems hearing anything after you have plugged a sound source into the 'Line In' socket of a Realtek soundcard (or motherboard onboard sound) then read on...

Plug your MP3 player (or other sounds source) into the 'Line In' socket and then go to the control panel and start the 'Realtek HD Sounds Effects Manager'. If you click the 'Audio I/O' tab you should see something like:



The highlighted part indicates that the Realtek HD Audio Manager knows that you have plugged a 'Line In' device in. You should now be able to record what is being played but you most probably won't be able to hear it!

A lot of audio cards give you the option of passing the line in through to the line out so that you can hear it on your speakers but this isn't the case with the Realtek audio.

What you have to do is ensure that the 'Rear Blue In' channel is not muted and has some volume as well as the 'Line In':



It took quite a bit of messing about to find this out, but it makes sense when you look back at the first screenshot and see that the line in socket is the blue socket. Why they can't label the 'Read Blue In' as 'Line In' I don't know!

Technorati Tags: , , , ,