Pages

Thursday, April 6, 2017

Dealing with Hardwired dependencies part 1 - An alternative to Dependency injection.

In this video, I show a little refactoring trick that can be used to unit test a method that has a hardwired dependency to an external system via an static method call. This is an alternative approach to dependency injection, which can be used when we are not sure about modifying the design of the class. In very large systems making design decisions such as adding another method to a constructor etc ... may have a big impact in design of both production and test harnesses. This trick can help you temporarily postpone your design decision and get you going with your unit testing.



Wednesday, April 5, 2017

Observer Design Pattern in Java

A very interesting, useful and popular design pattern that I like. Here a video with explanation and code example:


Tuesday, March 28, 2017

13 minutes TDD warm up

O wow! I haven't realised for how long I didn't write a blog post.  I better start posting again, but first... Let's warm up with a bit of TDD. Ok I've got 13 minutes, lets put on some music and see if I can do a Kata.

Note: To view in high resolution, open the full screen view and change the video quality using the wheel.

                                           
    The video is raw unedited, the music is coming from youtube in my second screen.13 roman digits, parsed in 13 minutes ;)


Monday, June 13, 2016

The Kick Off

What is this?
This document describes an internal(team) designed and agreed mandatory rules for the process that just precedes the development of a story, This process is commonly known as the "Kick Off".

Why?
The main reasons for this are:
  • to make sure that the team is aligned/understands the story that is about to be developed
  • distil the requirements given to the team by the business analyst and early spot errors in them
  • revisit and adjust the scope of the story if necessary 
  • create a mandatory repeatable process so the risk of early introducing an issue is less
  • agree upon work that need to be done

THE KICK OFF

  1. Read the story description independently
    Regardless of if we work in a pair programming environment or not, we(each member of the team individually)  will take some time in our own to read the requirements that were written in the ticket management tool(e.g JIRA). The time this first glance takes is somewhere around 5' and 20'.
  2. Gather questions
    We must understand that the kick off is a team activity. We are not expected to understand everything in the requirements at 100% neither to know exactly everything that needs to be done and how it should be done. We will write down all our concerns, doubts, assumptions, questions, etc... in a list and we will keep it for the time of the kick off. Individual solutionising is not an acceptable behavoir.
  3. Craft a task proposals list
    Now with our pair programmer or by our own if we don't have one, what we will do is to write down a list of proposed tasks, based on our understanding of the story so far. This list is just a draft, not a final decision. The purpose of this draft is:
    - To make visible to others our views/sense about the story in hands.
    - To make it easier for the developers to spot task parallelisation opportunities.
  4. Empty acceptance test
    An empty acceptance test(just text in the Given When Then format) will serve as a conversation starter during the kick off. The propper creation of the real failing acceptance test will be done as an independent task, later since only when all is clarified in what regards to requirements, we can write an accurate and meaningful acceptance test.
  5. The Kick Off
    At the kick off all the team gathers and look together at the story. The BA will start by giving a brief summary on what is the story about. Then the developers will show the empty acceptance test they've written. Now is the time to use the questions, assumptions we gather initially. If any discrepancy exist, it will be clarified by the team and the acceptance test will on spot be corrected. At this point, the story is considered to be kicked off with the team(but yet not officially marked as started).
  6. Dev's talkWhen the kick off is complete and we know exactly what needs to be done, we will huddle with the rest of the colleagues to distil the proposed task list we made and agree on what tasks we can parallel. It is highly likely that after the kick off toke place that initial draft is no longer accurate at 100% so the devs will revisit it and distil the final version. This final task will be published in the same place where the requirements were published, so the progress of the story is transparent to everybody.
  7. Start development
    The developers will now prepare their tools for development(e.g rebuild local DB, synchronise VCS, awake zombies...). When this is complete the developers will move the story into "dev in progress" and development begins. Good time for a coffee now ;p

Thursday, June 9, 2016

Mockito ArgumentCaptor example

Lets observe the following class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class MyService {

    private Collaborator collaborator;

    public MyService(Collaborator collaborator) {
        this.collaborator = collaborator;
    }

    public void doSomething() {
        Thing thing = new Thing();
        thing.setType("ABC");
        collaborator.doStuffWith(thing);
    }
}

If we were to test the method doSomething() what we would be interested in,
perhaps mostly is to make sure that the collaborator that it uses is reached and the appropriate
parameters are passed. We could do that very easily by just verifying on a mock

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MyServiceTest {

    private Collaborator collaborator = Mockito.mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldDoSomething() throws Exception {
        myService.doSomething();
        verify(collaborator).doStuffWith(any(Thing.class));
    }
}


But there is a peculiar thing about this method. The argument that is passed into the collaborator
function doStuffWith() its using an object. Objects as its well known, contain other objects and/or
primitive variables. Since the object thing its being created internally in the method rather than be
injected(Its a hardwired dependency), we have no way of accurately knowing about it anything else but its type. So if we were curious about knowing more precisely about that object, what we would have to do is to spy on it. Mockito, allows us to spy on the objects that are passed to the mocks using a little tool called Argument Captor.
Let's have a look at how this test would look like if we were spying the object thing.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class MyServiceTest {

    private Collaborator collaborator = mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldUseTheRightThing() throws Exception {
        ArgumentCaptor<Thing> argument = ArgumentCaptor.forClass(Thing.class);

        myService.doSomething();

        verify(collaborator).doStuffWith(argument.capture());
        assertThat(argument.getValue().getType(),is("ABC"));
    }
}

As you see, spying is an interesting way of in a non intrusive manner(without having to refactor), you can discover things about your code.

Now a question comes to our head. But declaring that object of type Thing in the method like that, is not an smell? Well, maybe but have in mind that if you were to inject that object from either the constructor or via a setter injection, we could say that you would be changing the api of the class. So that is not very good, because maybe you don't know if the clients that use the class are actually capable of providing the object thing or if would that even make sense form a design point of view.

To express this last point in a more pragmatical form, I am going to show you another 2 more intrusive refactoring to this class that could help you test that object, but that will need from you to sacrifice in design.  

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class MyService {

    private Collaborator collaborator;
    private ThingBuilder thingBuilder;

    public MyService(Collaborator collaborator, ThingBuilder builder) {
        this.collaborator = collaborator;
        this.thingBuilder = builder;
    }

    public void doSomething() {
        Thing thing = thingBuilder.withType("ABC").build();
        collaborator.doStuffWith(thing);
    }
}
If you had a builder, you could mock it and train it, but you would pay a design price of having to add the builder to the constructor.
Even if you choose to use a setter to set the builder or keeping the original constructor as it is(so you don't affect the clients) and overloading, you are still sacrificing your design for the purpose of the test. Your test would also become more complex. It would look like this:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");
        when(thingBuilder.withType(anyString())).thenReturn(thingBuilder);
        when(thingBuilder.build()).thenReturn(thing);

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }
The other alternative I was thinking about would be to override equals and hashcode, so you could do a comparison in your test against a newly created object that would be the
expectation.

1
2
3
4
5
6
7
8
9
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }

It looks naive, but again is intrusive. You are adding 2 methods in your entity, just for the purpose of making the test green.

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
public class Thing {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Thing thing = (Thing) o;

        return type != null ? type.equals(thing.type) : thing.type == null;

    }

    @Override
    public int hashCode() {
        return type != null ? type.hashCode() : 0;
    }
}

Wednesday, June 8, 2016

Remote debug - IntelliJ + Java + Gradle + SpringBoot

This brief video just shows how to hook IntelliJ's remote debug config.
If you want to try this yourself, here you can find the app I am using in this demo:
https://github.com/SFRJ/hitthegroundrunning




Debugging for hours and still you didn't found the bug? No panic, just call this guy, he can solve all your problems:




Wednesday, May 18, 2016

Retrospectives - "Who are those guys?"(Part 3)

Big IT companies are often very siloed environments. It's not uncommon to see everyone segregated by their role: Devs in one corner of the open space, testers in another, DBAs in another floor, SAs in a different building, project owners in another country, etc ... This silos are in my opinion very dangerous for the organisation and sometimes we are not even aware to what extend the environment is siloed. Let me give you an example:

Have you ever noticed how many developers that work in the same floor as you, say hi to you in the corridor while going to the toilet, the coffee machine or even at the street at lunch time? Interestingly, those who you frequently talk to would probably smile, say hi or give you some sort of greeting. But, there are others that when you cross paths, regardless that you work in the same floor as you for years, will look at the ground, at the sealing, at their phone or elsewhere just not at you. This are not people with a different role or rank than yours, this are the exact same people as you. So this little experiment shows to what extend the companies are siloed, If we are unable to say hi to each other when we cross paths, how on earth can we expect from us to be influential and drive change in an organisation?


Regardless of all this things, many recruiters still dare to write in their job specs the word 'Agile'. The obvious question arises: how is it possible for a little naive agile team to have significant impact in the overall organisation? All those cool 'Agile' ideas which could perhaps save millions, create a much better work environment for all, bring innovation ... are at the risk of slowly dying in the minds as time passes and the old school overwhelming corporate traditionalism just keeps on the same line of thought.

The answer to the question it's not brief and neither trivial to present since it's composed of many parts. But for now in this post I will gently scratch the surface of one of those partial answers, which is "Agile Influencing".

There is retrospective format which is actually a reverse organisational engineering exercise, which is specifically designed to help the agile self directed team, to pinpoint key players and elements in the organisation and craft and influencing plan that could help them gain some terrain (and who knows maybe even save some life's ;) ). Let's have a look at it.

Step 1 - Switch on the radar
At the retrospective, the facilitator will draw on the whiteboard, 3 concentric circles that will look like the image below. And will explain the purpose of each circle.



- The most inner circle will represent the areas of direct control by the team(e.g test environments, development tools ...). Of course all this areas will be different for different teams, maybe some team will have total control over their production database, while other team will not have the database under their control.

- The second circle represents the area of direct influence. This is the area where the team cannot directly control, but can influence(e.g line managers, other development teams, etc ...)

- The most outer circle represents what is totally out of reach for the team or even unknown(e.g Companies chain of command, board of directors ...)


Step 2 - Tuning the right frequency
The facilitator, will ask the team to decide on or many goals or topics, they feel they need influence in order to achieve it. And will ask them to stick them in the outer area of the circle.



Step 3 - Scouting
The facilitator will ask everybody to write in post-it notes, names resources(e.g hardware, software, databases, processes, etc ...) and also the names of people(e.g managers, team leaders ...) that could potentially be connected in one way or another, with the topics/goals in the outer area. They participant will put all this elements in any of the 3 circles based in how they consider their influence around them looks like.




Step 4 - Triangulating
In one way or another, either directly or indirectly elements that are on the board will be conected to the goal the team want's to achieve. Ask the members to draw dashed lines for those relationships they are less confident about and solid lines for those relationships they feel more confident about.



Step 5 - Firing
Once you know how things are connected, you can craft a plan for influencing. Don't worry if you don't get it right at the first go or you didn't really pinpoint the right person, this exercise will probably need to be repeated in multiple sessions, until the team discovers how to get to their goal. Every time write the actions you will take and assign them to your team members.



Tips to have in mind when crafting the strategy
- Not everybody equally aligned
People have different characters, priorities, ambitions... It is important to understand that many times the reality is that in the corporate environment people, for whatever reason pull in different directions. Being aware of this and understanding in which direction the influencers are pulling is key to develop a good tactic.

- People might ask for something in exchange
Sadly very few things are free this days, so don't be surprised if you have to often apply the first law of economics in order to get somewhere "If you want to get something, you have to give something away".


- Certain fears can be proven irrational
A well crafted proof of concept, an excellent presentation or maybe an in depth conversation with the right person, can help you win over hearts and minds. Many of the fears that people have when it comes to change are mainly founded in the uncertainty. If you are going to lead for change, you will have to lead by example.

- Where things are more obscure and unknown more light is needed
Don't confuse uncertainty/unknown from conflict of interest. Many influencers that are in a conflict of interest with you or your team will not tell you that directly. They will instead put some excuses such as risk, cost, time ... When in reality the real reason is probably just a self interest on guarding a position or a key resource. There is many of this scenarios, specially among management, make sure that you either bypass those influencers by finding others or ask more and more questions and clarifications when you suspect that their real reasons are not what they are saying they are. No matter how strong they are, never be afraid if your cause is just.

- Sum forces with those who suffer alike in order to gain greater visibility
You and your team are probably not the only ones, summing forces with others like you, no matter if you will have to negotiate certain things or arrange certain favours. The friends of your friends will become your friends and their influence will become your influence.


This article was part of  a series of articles I started writing time ago on retrospectives. Here my previous posts on the topic:


Retrospectives – “Discovering our selves”(Part 1)
Retrospectives – “Lets talk about it”(Part 2)
Meditating about the self directed I.T company
Why big corporations don't like retrospectives?





Share with your friends