Monthly Archives: February 2013

Java RSpec alternative

I simply adore RSpec in Ruby land 🙂 It helped me embrace TDD in the best manner possible – by not getting into my way. Doesn’t sound much but it feels great when TDD cycle is so fast and unobtrusive that one simple cannot help running the spec over and over again. I don’t know, for me it feels like “let’s run the specs once again, if nothing else than to see how fast they run”. Compulsive but I can’t help it 🙂

Anyway, I’ve been working on some Java projects these couple of weeks and wanted the same TDD comfort zone as I get with RSpec. And a combination of Mockito, JUnit and PowerMock seems to be doing the trick. How about some code?:

public final class Blender {
  // ...
}

public class CreateYummyShake {
  private Blender blender;

  public CreateYummyShake(Blender blender) {
    // ...
    this.blender = blender;
  }

  public Shake with(List fruit) {
    return mix(takeRipe(fruit));
  }

  private Shake mix(List fruit) {
    // mix the fruit using blender
    // put it in glass
    // ...
  }

  protected List takeRipe(List Fruit) {
    new FilterFruit(fruit).takeRipe();
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Blender.class})
public class CreateYummyShakeTest {
  private Blender blender;

  @Before
  public void setup() {
    fruit = new ArrayList();
    fruit.add(mock(Fruit.class));
    fruit.add(mock(Fruit.class));
    blender = PowerMockito.mock(Blender.class); // mock final class with PowerMockito
    subject = spy(new CreateYummyShake(blender)); // spy the subject of the test, we need this later
  }

  @Test
  public void createsYummyShake() {
    doReturn(ripeFruit).when(subject).takeRipe(anyCollectionOf(Fruit.class)); // intercept call to another use case, no need to test this since it has it's own test
    when(blender.blend(fruit)).thenReturn(...); // use PowerMockito mock as you would use a Mockito one
    assertArrayEquals(ripeFruit.toArray(), subject.with(allFruit).ingredients.toArray());
  }
}

Before I explain this, a quick disclaimer: this code is nowhere near perfect or even nice, but hopefully it server the purpose of exposing some details about the test tools used. Consider yourself warned 🙂

Anyway, as you can see, Mockito plays well with collaborators and other use cases in the code. However, it can’t mock final classes (and some other combinations too, but you can look it up if need be). That’s where PowerMock comes in. It does the job, and as a bonus it lets you use those mock with Mockito as if nothing changed.

Also, subject under test might be using some other collaborator (ripe fruit filter in this case) and have a hard connection to it. Now, usually this would be injectable and easily mocked in test, but for the sake of argument, how does one test this? By extracting access to that collaborator to a protected method and stubbing it’s result. Mockito offers the ability to spy the subject under test. This way, the extracted access method can be mocked and the test is simplified. A separate test for the collaborator should exist of course.

The rest of Mockito DSL and options is pretty nice. It it not as pleasant as RSpec but it comes pretty close. I’ve always liked how RSpec tests read like prose, and this comes pretty close. The only issue I have is with asserts, but that can’t be helped unless JRuby is used, but that’s another story altogether.

Lastly, if you use Maven, you need these dependencies:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.10</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-all</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>1.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito</artifactId>
  <version>1.5</version>
  <scope>test</scope>
</dependency>
Tagged , , , ,

Rails secret

Secret_token.rb has the word “secret” in it for a reason. Unfortunately, open sourced Rails applications tend to forged this. Ignoring the file in the SCM of your choice is not enough, the secret token is needed for Rails to work. So, how can we avoid publishing this information and still enable secret token configuration in production? The answer is simple. Either put you secret token in an .gitignored file and load it secret_token.rb or use the environment. So, how bout we use both?

class ConfigurationError < StandardError; end

secret_token_file = 'config/secret_token.yml'
secret_token = ENV['SECRET_TOKEN'] || secret_token = YAML::load(File.open(secret_token_file))[Rails.env]['token'] if File.exists?(secret_token_file)
raise ConfigurationError.new("Could not load secret token from environment or #{File.expand_path(secret_token_file)}") unless secret_token

Dealesque::Application.config.secret_token = secret_token

This configuration has the added bonus of being able to deploy on Heroku without any changes to the code.

SECRET_TOKEN can be added as environment variable or config var as Heroku calls them. The procedure is simple, open up your console and:


heroku config:set SECRET_TOKEN=...aba5a33f3dbad3b694f6154b...

And that’s it 🙂

Tagged , ,