Friday, August 23, 2013

Using custom matchers for POJOs with Mockito...

I was trying to do the "right" thing by using TDD while working on a project, and I hit what looks to be a common problem of figuring out how to tell mock objects what to return based on whatever the argument value was that was passed in to the mock's method. It is really easy to specify which values to look for if you are dealing with a simple data type, but it isn't as straight forward if the argument is a complex object. The solution I used is the one I found on StackOverflow.

Here is the code I used:
// member of test class
private MyWorker mockMyWorker = mock(MyWorker.class);
private List<String> listOfOutputValues;
private final String theValueIWant = "some test value";

The class I am testing will use a helper class named MyWorker in this example. The class being tested will call the method MyWorker.listOutputValues(SomeObject) to get a list of output values. The SomeObject has an attribute named someValue. I only want the MyWorker class to return the output listing if the someValue matches a specific value.

I added a "when" statement in the @Before section of the test class. The "when" statement uses the custom matcher to check the value of SomeObject.getSomeValue().

@Before
private void Setup() {
 listOfOutputValues = createTestOutputValues();

 when(mockMyWorker.
                listOutputValues(argThat(hasValidAttributeValue()))).
                   thenReturn(listOfOutputValues);
}

When the mockMyWorker.listOutputValues(SomeObject) method is called in the test code, then it will return the list of Strings if SomeObject.getSomeValue() equals theValueIWant. Here is how the custom matcher is defined in the test class:
// private method in test class
private Matcher<SomeObject> hasValidAttributeValue() {
 return new BaseMatcher<SomeObject>() {
  @Override
  public boolean matches(Object o) {
   return ((SomeObject)o).getSomeValue().equals(theValueIWant);
  }

  @Override
  public void describeTo(Description description) {

  }
 };
}

Monday, August 19, 2013

Ask the rubber duck...

Have you ever been moving along on a project and - BAM! - you hit a brick wall of a problem where it isn't obvious to you on how you should handle the problem?

I had that happen last night while I was working on a personal project. I had just read a post on codinghorror.com that mentioned a problem solving technique which involves asking a rubber duck whatever question you might have about a problem before you go to a teammate or boss. The idea is that if you take the time to formulate the question in an understandable way, and ask the question out loud, then you have a good chance of figuring out a solution to your problem by yourself.

I've had numerous times where I will start talking to a teammate about a problem I'm having and the solution will come to me while I'm explaining the issue.  While it is really helpful to be able to talk to a teammate to work through the problem, it is a lot less distracting to others, and much more rewarding, to work through the problem on my own.

I thought it might look a bit awkward if I started talking to inanimate objects at the house with my wife and kids there, so I decided to talk through the problem with my wife instead.  Of course it worked great!  I spent 5 minutes (maybe less) talking about the problem, and the solution came to me.  Next time I think I will go in the garage and talk out the problem.

I've also had similar success when going for walks.  I will specifically not think about the problem at first. About half way through the walk I will start to think about the problem I'm having, and the problem will usually seem a lot less confusing.

In any case, rubber duck or no rubber duck - talking through problems is extremely helpful.  You might look a bit crazy if you start talking to rubber ducks, but at least you will be able to get your work done.


Thursday, August 15, 2013

Great idea from Effective Programming book...

I was reading Jeff Atwood's book Effective Programming, which is based on his excellent Coding Horror blog, and came across a great suggestion. 

Git clone projects that you use.  Reason - if you encounter a problem while using some third party project, then you will better understand how to debug the problem.  You might be able to find and fix bugs in the third party project, but you might be just as likely to learn how you are using some other code incorrectly.

One step further - git clone interesting projects.  Reason - see how other people code and how it differs from what you do. Think about why you like some bit of code or why you don't like it.  The important thing is to have an opinion.  You can always change your mind later.

I've sort of been doing this, but I'm going to try to be more methodical about it now.  It seems like a great way to learn, and get faster at diagnosing root causes of bugs.

Sunday, August 11, 2013

Using git with Google Code projects on Windows...

I decided to host a project on Google code, and chose git as the source repository since that is what I am familiar with. The Google code project page presents an auto generated password when you first create your project for use when pushing changes. You can regenerate this password if you need to.

One drawback of using an auto generated password is that they are purposely hard to remember, and therefore are not quite as easy to type in accurately on the command line. The projects source section suggests the following:

Add the following to your .netrc. 
machine code.google.com login <you google email address> password [generated googlecode.com password] 

I had no idea what a .netrc file was, so I looked around. At least on *nix machines, the .netrc file contains auto login information that can be used by ftp and rexec commands.

From what I read it sounded like I just needed to create the .netrc file in my user's home directory with the line as it is listed above.  I created the .netrc file, but I was still being prompted for my username and password when I would attempt to push changes to the repository. I searched a little more and I found a comment by named Dave Borowitz saying that the file should be named _netrc on Windows machines.

I changed my file name to _netrc and then I was able to push changes without entering my password.  

I didn't spend a great deal of time looking for the answer, but I feel like I was a bit lucky as well. I think there should be a mention about naming the file _netrc on the Google project source page.