All entries for May 2006

May 15, 2006

JUnit 4.0; whats all the fuss (aka jumping on the annotations bandwagon)

Writing about web page http://www.instrumentalservices.com/index.php?option=com_content&task=view&id=45&Itemid=52

I love junit. I think it is probably one of the best pieces of software around. It easily allows developers to follow one of the best methodologies around; test driven development, or at least development with tests :)

I do not think JUnit is perfect; there are bugs (google for more details…), and I was really hoping JUnit 4.0 would solve some of them.

Unfortunately, JUnit 4.0 has “fixed” all the wrong things :( Of course, this is only my opinion, and I am very grateful for all their hard work, but I am dissappointed.

Basically; the main difference between JUnit 3.0 and 4.0 is the infrastructure used to setup and define tests…JUnit 3.0 uses abstract classes and naming conventions; JUnit 4.0 uses annotations. Arguably having to not extend a base class is always good (less pervasive), but I think this is less so with unit tests (see later)

In a nutshell Rather than having

public class MyTestClass extends TestCase {
  private Object myObject;

  public void setUp() {
    myObject = new myObject();
  }

  public void testFirstAssumption() {
    assertTrue("hello world", myObject.getHelloWorld());
  }

  public void tearDown() {
    myObject = null;  // completely unneccessar, but for illustration
  }
}

now you would do:

public class MyTestClass {
  private Object myObject;

  @Before public void setUp() {
    myObject = new myObject();
  }

  @Yest public void firstAssumption() {
    assertTrue("hello world", myObject.getHelloWorld());
  }

  @After public void tearDown() {
    myObject = null;  // completely unneccessary, but for illustration
  }
}

whats the difference; I am using annotations instead of naming conventions….what has it bought me in real terms... absolutely nothing. I still have to explicitly mark a test method, the setupMethod, tearDown method etc., I just use annotations instead of naming conventions.

I am of course being entirely unfair….you can do more things with the annotations like having more than one setup method, commenting out test methods (@Ignore), indicating your test expects an exception (@Test(expected=yourException) but so what?

The only thing of value is the @test(timeout=X) method which natively indicates that the test must execute within X milliseconds. Very useful; but there are already extensions to do this.

Extending framework classes are bad

It is true that frameworks which require you to extend a base class are so 1980s :) but with unit tests, I actually don’t think it is such a bad thing…. the problem is that you cannot extend your own class because Java doesn’t support multiple inheritence (for better or worse…). However, the point is that unit tests are supposed to be small atomic tests which test a single thing. They are not supposed to be complicated, hierarchical object graphs which build layer upon layer of logic. If I cannot understand what is happening from looking at a single unit test…I consider that unit test less than optimal. I know a lot of my coworkers dissagree with me on this, but I would rather see code duplication in a test method rather than a parameterised method … simply for understandability. Let me say it again, I think any unit test method should be self contained for readability. Yeah; go on, flame away :) The worst thing you can have is unit tests breaking because you have modified another unit test ;) Unit tests breaking because of changes to domain code is good, breaking because of changes to unit tests are bad. Very bad…

So, after that lengthy paragraph, the fact that JUnit 3.0 imposes a relatively inflexible infrastructure in which to write your unit tests is not so much a good thing, but it does prevent you over complicating your unit tests.

Summary

So, is JUnit 4.0 is a dissappointment, no (despite the previous paragraph). Do I think JUnit 4.0 is a massive improvement; no. I do see how annotations are useful (timing, repeating etc.), but I feel somewhat underwhelmed :)


May 10, 2006

SpringOne travel arrangments; Eurostar rocks :)

Writing about web page http://www.springone.com/display/SpringOne06/Home

So I am off to SpringOne in June and was googling for how much it would cost. Well the good news is that there are lots of hits on flying to Antwerp, some from £115 return :)

Only they aren't really that good. They either require leaving mid day on the Friday and take 7 hours because of 2 change overs(!!) or suddenly become £400 if you fly back on the Saturday.

Travelling from London City Airport is slightly better, although still quite expensive and painful to get to (from Leicester). Manchester is equally painful and East Midlands is a no–go.

I was basically faced with spending around £150 to attend at best a day and a half conference which is already costing me ~500 euros :(

After typing up a cancellation email, I noticed a link to train times to Antwerp… It turns out that Eurostar travels from London Waterloo to any station in Belgium from as littler as £29 each way! Bargain. They also arrive/leave at useful times as well. Eurostar drops you at the main central station in Bruxelles Midi, but it is only a one hour train to Antwerp, and I understand they are fairly regular. So, all I have to do is travel to London from Leicester by train. Initially, virgin are trying to charge me ~£50 each way, but I noticed a "value" link which when pressed shows you a list of really cheap tickets…those sneaky guys ;)

So, my travel arrangments are:

Leicester –> London Waterloo (£8!!!)

London Waterloo –> Bruxelles Midi (+ free ticket to any Belgium station) (£29.50)

way home:

Bruxelles Midi –> London Waterloo (£39.50)

London Waterloo –> Leicester (£8!!!)

A grand total of £85. That is cheaper than the cheapest one way flight to Antwerp that I could find (excluding air tax, travelling to London/BHam/Manchester etc.) and the journey door to door will be quicker and less stressful.

Long live Eurostar :)


May 09, 2006

A better explanation than mine :)

Follow-up to Java Pet Peeves #3:Lack of use of the final keyword from Colin's blog

This guys goes into the ins and outs of the final keyword. Not sure he is saying anything that I didn't, but he does say it better and as my wife keeps stating "it's not what you say, it is the way that you say it" :) :)

link


May 05, 2006

Spring Web Flow RC1.0 – mapping comments

Writing about web page http://www.springframework.org/documentation

So I have downloaded SWF RC1.0 and doing the upgrade. This post if really just for me to keep track of things :)

Input mapping when calling a subflow

The source must be an expression, i.e. ${model.someProperty} whereas the target must be text:
<mapping source="${model.uploadedFiles}" target="uploadedFiles"/>

Output mapping when calling a subflow

The source must be text i.e. someProperty whereas the target must also be text, but qualify the scope:
<mapping source="emptyFiles" target="flowScope.emptyFiles"/>

Input mapping for the subflow itself

The subflow must now explicitly slurp the inputs.
The source must be text i.e. someProperty whereas the target must also be text, but qualify the scope:
<mapping source="uploadedFiles" target="flowScope.uploadedFiles"/>

Output mapping for the subflow itself (i.e. end state)

The subflow must now explicitly export the results that the calling flow can slurp.
The source must be an expression i.e. ${flowScope.someProperty} whereas the target must be text:
<mapping source="${model.emptyFiles}" target="emptyFiles"/>

Essentially, when a subflow starts, the calling flow exports bits of its context into a generic map, so source is an expression, target is the key in the map. The subflow (when it starts) can slurp from that generic map using the known key, so source is the key, target is where in the subflow context it must be placed (as plain text, not expression).

When the subflow ends, it exports bits of its context using the same rationale; source is an expression, target is the key in the generic map. The calling flow can then slurp from that generic map; source is key, target is plain text description of where it is placed.

example:

  <flow ...>
    <subflow-state ...>
   <attribute-mapper>
      <input-mapper>
       <mapping source="${model.uploadedFiles}" target="uploadedFiles"/>
      </input-mapper>
      <output-mapper>
        <mapping source="emptyFiles" target="flowScope.emptyFiles"/>
        <mapping source="invalidFileNames" target="flowScope.invalidFileNames"/>
        <mapping source="invalidFileTypes" target="flowScope.invalidFileTypes"/>
        <mapping source="duplicateFiles" target="flowScope.duplicateFiles"/>
        <mapping source="createdFiles" target="flowScope.createdFiles"/>
      </output-mapper>
    </attribute-mapper>
    </subflow-state>
  </flow>

  



...









Note: nothing in here is the definitive way; but it does work :)


May 2006

Mo Tu We Th Fr Sa Su
Apr |  Today  | Jun
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31            

Search this blog

Tags

Galleries

Most recent comments

  • Interesting… While I'm not completely convinced in such microbenchmarks, I'm pretty sure that 1ms = … by Alexander Snaps on this entry
  • Hello. I bought the book yesterday. I was trying to find the source code for chapter 11 and chapter … by Suleman on this entry
  • http://woosight.net/account/login?username=demo by live mashup demo on this entry
  • Thanks mate .. This blog was really helpful. by Maaz Hurzuk on this entry
  • Ty. Not directly helpful for my problem, but pointed me in the right direction. You will also get th… by Mike E. on this entry

Blog archive

Loading…
Not signed in
Sign in

Powered by BlogBuilder
© MMXIV