I really like dot. It’s easy, it’s ascii und you can generate pictures (png, svg) out of it. And now a colleague of mine showed me plantuml. It’s so cool. This post is basically a reminder to myself how cool it is 🙂
Kategorie: Programmiersprachen
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.
http://en.miui.com/thread-1766-1-1.html
hauptsächlich für mich als Linkablage 🙂
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.
Six Stages of Debugging
- That can’t happen.
- That doesn’t happen on my machine.
- That shouldn’t happen.
- Why does that happen?
- Oh, I see.
- How did that ever work?
Parallele jUnit-Tests ausführen
Hatte ich gestern mal gesucht und folgendes gefunden:
Scheduling Junit tests with RunnerScheduler for a concurrent execution | junit.org
Inzwischen hab ich eine einigermassen gepflegte Kontaktliste, Google Contacts sei Dank. Früher hatte ich ein kleines Skript das über meine Datenbank gegangen ist und die heutigen und morgigen Geburtstage rausgesucht hat und per E-Mail verschickt hat. Hier mal die Version für Google Contacts/Calendar:
#!/bin/bash TODAY=$(date +%Y-%m-%d) # 2010-03-30 TOMORROW=$(date --date=tomorrow +%Y-%m-%d) TODAY2=$(echo ${TODAY} | cut -d "-" -f 2,3 ) TOMORROW2=$(echo ${TOMORROW} | cut -d "-" -f 2,3 ) YEAR=$(echo ${TODAY} | cut -d "-" -f 1 ) FOUND="false" google calendar list --cal '.*birthday.*' --date ${TODAY},${TOMORROW} --field title | grep "^[^[]" | sed -e "s/'s birthday//g" > /tmp/file.txt while read line; do LASTNAME=$(echo $line | rev | cut -d " " -f 1 | rev) BIRTHDAY=$(google contacts list "$LASTNAME" --fields birthday | grep "${TODAY2}\|${TOMORROW2}") if [ "${BIRTHDAY}" != "" ]; then BIRTHYEAR=$(echo ${BIRTHDAY} | cut -d "-" -f 1) echo "${line}: ${BIRTHDAY} -> $(( ${YEAR} - ${BIRTHYEAR} )). Geburtstag" FOUND="true" fi done < /tmp/file.txt if [ "${FOUND}" == "false" ]; then echo "no birthdays" fi rm /tmp/file.txt
Potthässlich, aber funktional. Man braucht dafür zwei Dinge
- https://code.google.com/p/googlecl/
- http://www.google.com/support/calendar/bin/answer.py?hl=en&answer=37098 -> More -> „Contacts‘ birthdays and events“
Wird bei mir per Cronjob aufgerufen und produziert dann beispielsweise sowas:
Peter Test: 1981-11-05 -> 29. Geburtstag Karlheinz Mustermann: 2009-11-06 -> 1. Geburtstag
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.
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
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
- http://www.torsten-horn.de/techdocs/java-concurrency.htm#Irrtuemer
- http://www.java-blog-buch.de/0407-weitere-modifizierer/
WJAX-Challenge
http://it-republik.de/jaxenter/wjax09/challenge