Posts

Showing posts from 2018

QuickTip (Spock): Remember to add asserts when creating helper methods in spock tests

This is very similar to my blog post about  using .each in Spock tests . The Problem Having helper methods in a large spec is generally a good practice. For example, we use this pattern a lot is in testing lists of results. def 'test that does some stuff'() { given: String someFieldName = 'someOtherValue' when: List<SomeType> someResults = service.someAction(someParam) then: someResults.each { assertResultContainsAllTheseThings(it) } } . . . private boolean assertResultContainsAllTheseThings(SomeType result) { result.someFieldName == 'someValue' result.someOtherField == 'someOtherThing' result.someList.size() == 3 } I've run into lots of problems with tests not failing when they should have because I forgot to do this. The Solution If you can already tell what's wrong with this code, congrats! If you can't, when copy pasting that original check from the then block into...

The journey to a BMI of 29

Image
If you are only interested in my tech blog, then skip this one. It's a personal story. Back Story A few weeks before I left the US for Denmark in the summer of 2016, I hit the highest weight I've ever been and a BMI of 37.4. I still thought I was pretty healthy though. After all, I was walking 5 miles (8 km) a couple times a week and biking 5 miles (8 km) to/from work once a week. 🤦‍♀️ Although there are no full body pictures from that time, I do have a picture from my first few days in Denmark(red shirt/left). I distinctly remember trying on several outfits that morning and those were the only pair of shorts I had that fit. And by this point, I'd already lost 5 pounds (2.25 kg) during the move. Moving to Denmark and living on a very strict student budget meant making some major changes to my life. I no longer had a car to drive everywhere. I had to walk to/from public transportation. I no longer had money for restaurants and fast food and had to buy my own groc...

Getting Started with Groovy Applications and the Gradle Init Plugin

Image
When working with groovy, there are several ways to get started.  Most tutorials, including my own workshops, use the GroovyConsole as a way to write small scripts and then save them to run later. What comes after that though? How can one build a slightly larger example without all the excess of a framework like Spring Boot or Grails? With this article, I will show you how to use the Gradle init plugin to create a small runnable, testable Groovy application. Before we start you should have a local installation of Gradle 4.0+. If you don't have Gradle installed or your version is less than 4.0, I highly suggest you manage your Gradle installations with  SDKMAN . In a clean directory run the following command:   gradle init --type groovy-application After running that command, you should see several new files. The Gradle files are for building and running the project and your project code will be in the src directory. To start working open the pr...

QuickTip (Spock): Stubbing with null

This is less of a problem and more of a code style thing, but I noticed recently that some of our Spock code has several instances of >> null. For example: ... then: result 1 * service.doSomething() >> new Blah() 1 * service.doSomethingElse() >> null ... It's nice to see that the interactions are written in the same style, but for many methods 1 , Spock returns null by default so writing the >> null is redundant and I prefer to remove it. Do you agree or not? Feel free to comment below. If this is something we agree on, perhaps it should be a new codenarc rule.

QuickTip (Grails): Grails LinkGenerator

The Problem Recently, I was using the Grails Link Generator in a service.  I was using IntelliJ so as I added the dependency at the top of the class using the same name as the class. It looked something like this: package com.example import grails.web.mapping.LinkGenerator class ExampleService { LinkGenerator linkGenerator String doSomething() { ... } } It took me a long time to debug this. Luckily, I had written a test. There was no compilation error, but the test picked up that linkGenerator was null. Of course, I was stumped. I tried checking the mocks in the service and various other debugging strategies but had no luck.  I looked through tons of other examples online until I noticed the one small difference between my code here and theirs... the name! The Solution To make the LinkGenerator work correctly, it needs to be called grailsLinkGenerator exactly. Hopefully, if you come across this post because you made the sa...

QuickTip (Spock): Don't use .each in a then block!!!

This happens time and time again. QA finds a bug and I swear I wrote a test for that condition. So, I go back to try to debug that test.  I see the original test I wrote and the condition that should fail.  It looks something like this: when: List<SomeType> someResults = service.someAction(someParam) then: someResults // assert the result is not null, empty list, etc someResults.each { it.someFieldName == 'someValue' it.someOtherFieldName == 1 } In this case, someOtherFieldName is empty but the test still passes... wtf?! right? Well, this is actually the expected behavior. Because each doesn't actually return anything from the closure but just returns the collection itself, Spock thinks it is fine.  It doesn't care about the lines within the each block and whether they fail or not. So we have a few choices here: use .every (only applies to the last line) when: List<SomeType> someResults = service.someAc...

QuickTip: Reversing Sort Order in Groovy

One of the great things about Groovy is that there are multiple ways to get **it done. This means people learning Groovy and especially those coming from other programming languages can use the same syntax and practices they are already familiar with. However, this may result in some small mistakes or inefficiencies. The first one I want to highlight today is reverse sorting. So given: class Person { String name Integer age } If we want to sort a list of people by their age, we would normally use: people.sort { it.age } To reverse the list, we have several options including: people.sort { it.age }.reverse() or: people.sort { -it.age } The first one, I see a lot. It's easy to write and to think about, but it's not as efficient as the second one. Why sort the list and then reverse it, when you can sort by the criteria you want in the first place? The next problem comes with the '-' notation. It works great for examples like t...