Friday, September 27, 2013

The Law of Demeter will tell you the truth

    The Law of Demeter (LoD) is well-known in object oriented programming. Can we get to know something unusual from that principle?
Overall, LoD can provide us interesting metrics. Let's follow up with the example. We have three simple classes:
class A {
    private B b;
    public String getTarget() {return b.getC().getTarget();} 
}
class B {
    private C c;
    public C getC() {return c;} 
}

class C {
    private String target;
    public String getTarget() { return target;} 
} 
When I see presented piece of code I am pretty sure that class A was not unit tested. What is more, LoD is broken because of the fact that A knows about the existence of C:
b.getC().getTarget()
Why do I think that A was not unit tested? Because it requires a lot of effort to unit test such a class (even with tasty Mockito):
@RunWith(MockitoJUnitRunner.class)
public class ATest {

 @InjectMocks
 private A a;

 @Mock
 private B b;

 @Test
 public void shouldTestTarget() {
  // given
  C c = mock(C.class);
  when(c.getTarget()).thenReturn("target");
  when(b.getC()).thenReturn(c);

  // when
  String target = a.getTarget();

  // then
  assertEquals("target", target);
 }
}
and programmers are usually lazy personas. Now, let's follow LoD:
public class A {
    private B b;
    public String getTarget() {return b.getTarget();} 
}

class B {
    private C c;
    public String getTarget() {return c.getTarget();} 
}

class C {
    private String target = "target";
    public String getTarget() { return target;} 
} 
and let's test class A:
@RunWith(MockitoJUnitRunner.class)
public class ATest {

 @InjectMocks
 private A a;

 @Mock
 private B b;

 @Test
 public void shouldTestTarget() {
  // given
  when(b.getTarget()).thenReturn("target");

  // when
  String target = a.getTarget();

  // then
  assertEquals("target", target);
 }
}
Can you spot the difference?

No comments :

Post a Comment