23

Is it appropriate and necessary to test getters and setters?

I think they haven't any logic and they can't crash or throw any exceptions.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shikarn-O
  • 3,337
  • 7
  • 26
  • 27

6 Answers6

16

You should not unit test DTO's getters and setters, unless they contain some complex logic that requires testing.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Luciano Fiandesio
  • 10,037
  • 10
  • 48
  • 56
  • If the DTO uses an auto-convert mechanism, like from `ModelMapper` I'm not sure. I had some tests failing because it didn't map everything correctly. Can be annoying to search a tests for its flaws while the problem lies in the dtos. – codepleb Jun 08 '17 at 09:35
10

Using modern tools it's not much of an effort:

import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor;
import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanEquals;
import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanHashCode;
import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanToString;
import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNotNull;

public class Test {

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void testFlatFileReaderMetadata_Parameters() throws Exception {

        assertNotNull(new Test());

        assertThat(Test.class, allOf(hasValidBeanConstructor(), hasValidBeanEquals(), hasValidGettersAndSetters(),
                hasValidBeanHashCode(), hasValidBeanToString()));
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user666
  • 1,104
  • 12
  • 20
  • 1
    and in addition you can use `@ParaterizedTest` with several classes as `@ValueSource` – cuh Oct 21 '20 at 19:15
8

I'm reading GOOS at the moment, and the authors suggest that you don't write test cases for your «value objects» (e.g. DTO's).

Coverage for the coverage's own sake is never good. "Tests should be meaningful", as Karl Seguin puts it.

Martin R-L
  • 4,039
  • 3
  • 28
  • 28
  • While I fully agree with "Coverage for the coverage's own sake is never good", this is not what this question is about. Testing a DTO class is not about distrusting _the language_ being able to shuffle the data correctly in and out of it. It's about distrusting future _developers_ being able to maintain the "DTO contract" of the class. By "DTO contract" I mean that "Every getter should always return the latest value supplied to its corresponding setter". "But hey come on! No one will put some "logic" into a DTO and break _that_, will they?" Yes, they will. – Mikko Östlund Dec 02 '20 at 12:53
2

If the code for getters and setters is generated, I would assume it is correct. This is a major drawback of not having properties at language level - you have a lot of generated code that is checked-in into source control and should be tested because it screams red in coverage reports.

On the other hand, even a simple getter might be incorrect, for instance due to C&P error:

private String foo;
private String bar;

String getFoo() {return foo;}
String getBar() {return foor;}

My final thought: getters and setters are implicitly tested when appropriate logic using them is tested. Setter not covered in tests? - probably you are never setting this field and it might be final? Only setter but no getter called? - useless field?

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 2
    static code analysis should spot unused fields and all those stuff, no unit test required in my opinion. – quadroid Jan 27 '15 at 11:42
1

You might need to/forced to unit test getters and setters for a couple of reasons:
1. Code coverage 2. Automated regression testing

In these cases you could use libraries that generate these junit test cases, or, write a single utility method using generics to set an object, get it back and compare if they are equal.

CMR
  • 986
  • 7
  • 16
0

This function doesn't change anything at this string... --> no complex setter

setTest(String test) {
   this.test = test;
}

but if you have something like that, it would make sense to test it (because someone could have changed the token e.g.):

String token=";";
   setTestTwo(String testTwo) {
   this.testTwo = testTwo + tokenString;
}
eav
  • 2,123
  • 7
  • 25
  • 34