Saturday, January 08, 2011

Eclipse Hamcrest Runaround

I started reading Growing Object-Oriented Software and it talked about using the Hamcrest matchers with jUnit. It sounded like a good idea so the next time I was writing a test I tried using them.

The first problem is where to import assertThat from. That turned out to be easy, it's in org.junit.Assert along with the normal assertEquals etc.

The next question is where to import the matchers like equalTo. I found that in org.hamcrest.Matchers.

Next I wanted a lessThan matcher but I couldn't find it.

It turns out jUnit only includes Hamcrest core which doesn't have lessThan. I searched on the internet and didn't find a lot of help. I found a question on StackOverflow that suggested replacing the Eclipse supplied junit and hamcrest-core with junit-dep and hamcrest-all

I tried this and at first it seemed to work ok. But then I went to build my jars and Proguard gave all kinds of errors about missing dependencies.

I've been meaning to look into Maven and it's supposed to handle dependencies, so I thought I'd give it a try. Since I'm using Eclipse I looked for an Eclipse add-on for Maven. I found one and installed it. Big mistake. Not only did it not help with the dependency problems (at least I couldn't figure out how) but it also messed up my project. No problem, I thought, I'll just uninstall it. Except it left a mess behind. I ended up restoring my Eclipse install, but I still had problems. I kept getting errors referencing maven but I couldn't find any references to maven in my project. Eventually I found that the launch configurations for your project are stored in the workspace, not in the project. (That doesn't make much sense to me, but I'm sure there's some good reason.) After I deleted those (easier than trying to fix them) things were back to before the Maven detour.

It said I was missing jMock and EasyMock so I went and found those jars and added them. But it still wanted some kind of Ant jar. That seemed like a little much.

I saw there were various other jars for Hamcrest but frustratingly, no explanation of them. (I did find someone had filed an issue that there should be an explanation, but no one had responded.) I downloaded the complete package and it contained a readme that gave some explanation. It looked like I wanted hamcrest-core and hamcrest-library rather than hamcrest-all.

That eliminated the dependencies on jMock and EasyMock and Ant. But I still got an error that junit was referencing something that was missing from hamcrest. I thought maybe it was a version issue, so I tried multiple versions of junit and multiple versions of hamcrest but no luck.

Then I realized that the junit supplied by Eclipse includes hamcrest-core. So maybe all I needed to do was go back to that, and then add hamcrest-library. Sure enough, that did the trick.

No doubt the junit and hamcrest and eclipse folks would say, of course, it's obvious. But it sure wasn't obvious to me.


Anonymous said...

True dat! I've had the runaround for an hour looking for lessThan, thank god I found your page - helped restore a bit of my sanity :P

Andrew McKinlay said...

Glad I could help!