Tesing a simple calculator class with JUnit/JMock I'm playing around with JMock and trying to understand whether I understand the idea correctly.

There's an interface Printer aimed to print integers somewhere. There's an interface Calculator aimed to perform math. There's a class CalculatingMachine aimed to connect Calculator and Printer: first, it calculates the result with Calculator and then this result is passed to Printer. Here's the code

public class CalculatingMachine {       
    private final Printer printer;
    private final Calculator calculator;

    public CalculatingMachine(Printer printer, Calculator calculator) {
        this.printer = printer;
        this.calculator = calculator;
    }

    public void processAdd(int x, int y) {
        int result = calculator.add(x, y);
        printer.print(result);
    }

    public static interface Printer {
        void print(int x);
    }

    public static interface Calculator {
        int add(int x, int y);
    }   
}


As far as I understand CalculatingMachine only requires one test: we need to make sure IT USES calculator to do the math and then we need to make sure IT USES printer to print the result. So, here's my test:

public class CalculatingMachineTest {       
    @Test
    public void testCalculatingMachine() {
        Mockery context = new JUnit4Mockery();

        final Printer printer = context.mock(Printer.class);
        final Calculator calculator = context.mock(Calculator.class);

        context.checking(new Expectations() {{
            oneOf(calculator).add(1, 2);
            will(returnValue(3));

            oneOf(printer).print(3);            
        }});

        CalculatingMachine machine = new CalculatingMachine(printer, calculator);
        machine.processAdd(1, 2);

        context.assertIsSatisfied();
    }
}


Pretty straightforward and does what it supposed to do. There are 2 points I'm curious about:


Is it the right approach even though CodePro says that CalculatingMachine itself has 19 lines of code, though test for it is 23 lines of code? I'm just not sure: is it normal to write more tests then code that does something?
Is there any other way to test all the same but with less code?
This is technically correct code, whether it's right depends... 

This might be the first test for an object that will become more complicated. It's reasonable to start small and work your way up. 

If the Calculator is a self-contained implementation that doesn't pull in other dependencies, it might be better to just use a real one. In this case, it looks more like a function.

In the end, there might well be more test than production code because you want to exercise all the paths. These days, I find myself writing unit tests with mocks at a slightly higher level, around a small cluster of objects.

If the call to the Calculator doesn't change the state of the world outside the Machine, I'd probably use an allowing clause, we "Stub Queries, Expect Actions"

allowing(calculator).add(1,2); will(returnValue(3));


it's the same implementation underneath but expresses the intent more clearly.

You might try the JUnitRuleMockery with JUnit's @Rule. It takes care of the assertion housekeeping at the right time.

And before someone jumps in with their favourite alternative mocking framework, I'm not sure that's really the point. We can shave a few lines off here and there, but it's more important to understand the design issues. And everything will change with Java 8.