EasyMock, Unitils and a mixture of both

So, we do use unitils and easymock for quite a while now. We do our mocking with easymock and use the unitils-inject and unitils-easymock modules to simplify our tests.

But, there was a very weird behaviour. So I tried to boil it down to the reason why it fails. Here is some code that we actually want to test:

package de.matthiascoy.easymock.easymockprimitivetest;
public interface InterfaceB {
    void foobar(boolean b);
}
package de.matthiascoy.easymock.easymockprimitivetest;
public class TestedObjectClass {
    private InterfaceB interfaceB;
    public void runMe(boolean b) {
        interfaceB.foobar(b);
        interfaceB.foobar(b);
    }
}

So, obviously we want to test toe runMe-method and want to verify that the two calls on the interfaceB are actually done with the given arguments. Our first try was this code:

package de.matthiascoy.easymock.easymockprimitivetest;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.easymock.EasyMockUnitils;
import org.unitils.inject.annotation.InjectIntoByType;
import org.unitils.inject.annotation.TestedObject;

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class EasyMockAndUnitilsTest {

    @TestedObject
    private TestedObjectClass testedObject;

    @InjectIntoByType
    private InterfaceB interfaceB;

    @Before
    public void setUp() {
        this.interfaceB = EasyMock.createMock(InterfaceB.class);
    }

    @Test(expected = AssertionError.class)
    public void testPrimitiveBoolean() {
        boolean B = true;

        interfaceB.foobar(B);
        EasyMock.expectLastCall();
        interfaceB.foobar(!B);
        EasyMock.expectLastCall();
        EasyMockUnitils.replay();

        testedObject.runMe(B);

        EasyMockUnitils.verify();
    }
}

What you can see is, that we do expect first TRUE and then FALSE, but that should fail. We do test that with the „expected=AssertionError“ value in the @Test annotation. But actually this tests fails, because there is no AssertionError. With just a „@Test“ the test just runs and shows us a green light. That’s very strange. So, we thought: must be a bug in the testingframework, but which one?

So, we created a EasyMock 3.2 only test

package de.matthiascoy.easymock.easymockprimitivetest;

import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.EasyMockSupport;

import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EasyMockRunner.class)
public class PureEasyMockTest extends EasyMockSupport {

    @TestSubject
    private TestedObjectClass testedObject = new TestedObjectClass();

    @Mock
    private InterfaceB interfaceBMock;

    @Test(expected = AssertionError.class)
    public void testPrimitiveBoolean() {
        boolean B = true;

        interfaceBMock.foobar(B);
        EasyMock.expectLastCall();
        interfaceBMock.foobar(!B);
        EasyMock.expectLastCall();

        replayAll();

        testedObject.runMe(B);

        verifyAll();
    }

    @Test(expected = AssertionError.class)
    public void testPrimitiveBooleanWithEq() {
        boolean B = true;

        interfaceBMock.foobar(EasyMock.eq(B));
        EasyMock.expectLastCall();
        interfaceBMock.foobar(EasyMock.eq(!B));
        EasyMock.expectLastCall();

        replayAll();

        testedObject.runMe(B);

        verifyAll();
    }
}

This test does work. So, easymock seems not to be the problem. Now, to unitils:

package de.matthiascoy.easymock.easymockprimitivetest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.inject.annotation.InjectIntoByType;
import org.unitils.inject.annotation.TestedObject;
import org.unitils.mock.Mock;

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class UnitilsTest {

    @TestedObject
    private TestedObjectClass testedObject;

    @InjectIntoByType
    private Mock<InterfaceB> interfaceB;

    @Test(expected = AssertionError.class)
    public void testPrimitiveBoolean() {
        boolean B = true;

        testedObject.runMe(B);

        interfaceB.assertInvoked().foobar(B);
        interfaceB.assertInvoked().foobar(!B);
    }
}

And this test just works fine as well. So, the problem must be somewhere in the middle. I’m still not sure where exactly, but the second call to interfaceB.foobar in EasyMockAndUnitilsTest.testPrimitiveBoolean does not care about the arguments. It does care about if it’s called or not, but the argument is ignored.

So, we decided to migrate all our tests to pure easymock. Maybe, somehow we will move to mockito at the end … maybe.

ant + bad version

Ich  hatte die ganze Zeit ein Problem, dass wenn ich mein JAVA_HOME auf java5 gebogen habe, dass sich ant verabschiedet hat mit

java.lang.UnsupportedClassVersionError: Bad version number in .class file

Also noch bevor überhaupt das build.xml ins Spiel kam. Nach ein bissle recherche liegt es daran, das die xerces-XML-lib in ubuntu ohne target gebaut ist und somit auf 1.6 steht. Das klappt dann natürlich nicht mit 1.5.

Der Fix den ich jetzt gemacht habe ist relativ trivial:

http://packages.ubuntu.com/de/quantal/all/libxerces2-java/download

dort, eigentlich vor seiner Zeit (Quantal ist ja noch nicht stable) wurde das target wieder auf 1.4 gesetzt und somit klappts auch mit den Nachbarn.

Fehlermeldung des Tages

svn: Cannot create new file ‚/home/myuser/programs/eclipse/workspace-java/someservice/somemodule/src/test/config/default/datasets/.svn/tmp/prop-base/toller.langer.package.name.deutlich.laenger.als.hier.angegben.xml.svn-base.76854713-2901-0010-b32d-edbcf3a145b9.tmp‘: File name too long

Super.

Fast schon Weihnachten

Jaja, wie die Zeit rumgeht. Schon wieder über einen Monat her das ich was geschrieben habe. Nunja, was kann ich erzählen … nicht soviel und das auch erstmal nur in Kurzform:

  • SCJP: Ich  hab mal angefangen da das Buch durchzulesen und werd das dann mit Marc und Stephan auch durchziehen, inkl. Prüfung. Mein Chef hat mir dann noch BlackBelt empfohlen.
  • SingStar: Ich bin ja stolzer Besitzer einer Playstation und wir (d.h. meine Arbeitskollegen und ich) haben schon eine Party veranstaltet. Morgen findet die nächste Iteration statt und, so wie es aussieht, werden wir das alle zwei Wochen durchziehen 🙂
  • Code Review: Haben wir jetzt schon zweimal durchgeführt. Gibt immer wieder spannende Diskussionen, manchmal auf Quellcode-Ebene, manchmal eher auf Prozess-Ebene. Aber immer gut und hitzig 🙂
  • Speeddating: Einmal durchgeführt. Mal schauen wie es sich entwickelt 🙂

Das wars auch schon. Da ich vermutlich bis Weihnachten nichts Neues schreiben werden, wünsche ich einfach mal:

FROHE WEIHNACHTEN

W-Jax 2009: Donnerstag

Historisch gewachsen? Architekturen dokumentieren und kommunizieren
Prinzipiell ein interessanter Vortrag, wie man Architekturen dokumentieren kann. Verweist ziemlich häuft wieder auf arc42-Template, aber das macht ja nichts. Sonst halt viel UML und BlaBla, wobei UML hier nur gewählt wurde, weil sich der Vortragende damit auskennt (kommt ja von Oose)

Details des Java-Memory-Modells: volatile-, final- und atomic-Felder – Angelika Langer
Das war ein spannender Vortrag. Was genau bewirken eigentlich diese Felder? Inwiefern geben sie Garantien ab? Was können Sie leisten und was nicht? Welche kann man in manchen Fällen als synchronised-Ersatz verwenden? Da ich diese drei Felderbezeichner bisher noch nie wirklich verwendet hatte (ausser final), fand ich es unglaublich faszinierend mal ein bißchen stärker in Thread-/Parallelprogrammierung reinzuschnuppern. Ich empfehle als Lektüre da auch mal

WJAX-Challenge
http://it-republik.de/jaxenter/wjax09/challenge