Is there a Java unit-test framework that auto-tests getters and setters? [closed]
Asked Answered
C

10

43

There is a well-known debate in Java (and other communities, I'm sure) whether or not trivial getter/setter methods should be tested. Usually, this is with respect to code coverage. Let's agree that this is an open debate, and not try to answer it here.

There have been several blog posts on using Java reflection to auto-test such methods.

Does any framework (e.g. jUnit) provide such a feature? e.g. An annotation that says "this test T should auto-test all the getters/setters on class C, because I assert that they are standard".

It seems to me that it would add value, and if it were configurable, the 'debate' would be left as an option to the user.

Cyler answered 20/9, 2008 at 16:43 Comment(2)
Yes. See nl.jqno.equalsverifier.EqualsVerifier and javacodegeeks.com/2014/09/tips-for-unit-testing-javabeans.htmlSimmon
See pojo.pl/comparison (may be outdated though since the GitHub page says the project is not maintained anymore).Radical
D
9

Unitils does this w/ the static method assertRefEquals.

Dipterous answered 21/9, 2008 at 0:19 Comment(0)
B
17

I created the OpenPojo project for solving this exact problem.

The project allows you to validate:

  • Enforce Pojo coding standard (i.e. All fields private, or no native variables, ...etc)
  • Enforce Pojo behaviour (i.e. setter does JUST setting, no transformation, etc)
  • Validate Pojo Identity (i.e. Use annotation based equality & hashcode generation)

See Tutorial

Beesley answered 25/2, 2011 at 19:36 Comment(4)
My qualm is with the name: that you aren't testing POJOs you are actually testing Java Beans. "The term "POJO" is mainly used to denote a Java object which does not follow any of the major Java object models, conventions, or frameworks." the getter/setter is a convention. "Java Beans are serializable, have a 0-argument constructor, and allow access to properties using getter and setter methods.".Jijib
Note: you have to use it in your code for generating hashcode, equals and toStringDemarche
@ArtB - The wiki entry you link to defines a JavaBean as a type of POJO: "A JavaBean is a POJO that is serializable, has a no-argument constructor, and allows access to properties using getter and setter methods that follow a simple naming convention."Morisco
@JonathanSterling "POJO" was just a term invented to give a sexy name to classes that weren't limited by some framework, library, or convention. So to have a library for testing the specific conventions around beans named after "POJO" (which IMHO is best translated as "free form") isn't the best use of nomenclature... but I have used and recommended the library before.Jijib
U
14

I'm not aware of any readily available library or class that does this. This may mainly be because I don't care as I am on the side of strongly opposing such tests. So even though you asked there must be a bit of justification for this view:

I doubt that autotesting getters and setters benefit your code quality or your coverage: Either these methods are used from other code (and tested there, e.g. 100% covered) or not used at all (and could be removed). In the end you'll leave getters and setters in because they are used from the test but nowhere else in the application.

It should be easy to write such a test, e.g. with Apache Commons BeanUtils, but I doubt you really need it if you have good tests otherwise.

Ulphia answered 20/9, 2008 at 16:50 Comment(3)
We once had to implement tests like that because the getters and setters were only used in a dependent project and as such not touched in the unit tests of their own project.Unsheathe
Late comment - sorry: This would most likely be for code coverage reasons. You might need to do that for these reasons, but I doubt you'll get quality tests from it. I can easily write crappy tests that provide 100% coverage without any benefit at all. Was that why you "had to"?Ulphia
I do see value, although limited. People often copy/paste getters and setters. When they do, they sometimes forget to do one of the edits, A simple generated test could catch that.Kaleena
D
9

Unitils does this w/ the static method assertRefEquals.

Dipterous answered 21/9, 2008 at 0:19 Comment(0)
C
7

In the most cases setter and getter do more as only setting and getting an internal field. An Object has to check internal rules that it hold only valid values. For example

  • are null values possible?
  • are empty strings possible?
  • or negative values?
  • or a zero value?
  • or values from a list are valid?
  • or is there a maximal value?
  • or is there a maximum precision on BigDecimal values?

The unit test should check if the behavior correct if there invalid values. This can not be automated.

If you have no logic on the setter and getter then it must be used anywhere in your application. Write a test where your object is a parameter for a more complex test. You can test it then with different values from the list.

Test your business logic and not the getter and setter. The result should also a coverage of the getter and setter. The methods should be any result in your business logic also if you have only a public library. If the getter and setter have no code coverage then removed it.

Chickweed answered 20/9, 2008 at 18:47 Comment(0)
P
5

I've done something like that. A simple java class that takes an object and test all the getters and setter methods. http://sourceforge.net/projects/getterandsetter/

I do think you should avoid getter and setter methods as much as possible, but as long as they're around and it takes two lines to test them, it's a good thing to do it.

Pals answered 25/10, 2008 at 21:2 Comment(0)
O
3

I'll favor OO design over code coverage, and see if I cannot move those fields to the class that needs them. So I would try to see if those getters and setters can be removed, as suggested before. getters and setters are breaking encapsulation.

Oppose answered 20/9, 2008 at 17:7 Comment(0)
E
2

I am trying out openpojo

I have kicked the tires and it seems to do the job.

  1. It allows you to check all the pojo's in your project.
  2. It seems to check the best practices on pojo's

Check this tutorial for a quick start Tutorial

Ellis answered 4/2, 2011 at 19:13 Comment(3)
I have a problem with openpojo. For classes that "extends" a base class, openpojo looks for "declared" fields. Eg: abstract base class has 4 fields and concrete derived classes has 2 extra fields, only 2 fields will be tested.Nonchalant
@TitiWangsabinDamhore I don't see the problem, if they are setters & getters then there is no other interaction then they will be tested as part of the parent/base class. The only situation I can imagine it mattering is if the field was protected, and the sub-class had stricter validation occurring in the setter than the parent class.Jijib
@ArtB the problem occurs when the base class is abstract. Eg. AbstractHouse has 2 fields, 2 setter methods and 2 getter methods. There is sub class. ExpensiveHouse extends AbstractHouse it has 1 extra field, 1 getter and 1 setter. When I test ExpensiveHouse, open pojo looks at the declared field and executes 1 setter method and 1 getter method. Cobertura reports that AbstractHouse was not tested. Anwyay, this was my problem in 2014, not sure if OpenPojo still behaves this way. If I do test(new AbstractHouse(){}); this the declared fields are nothing and no setters or getters are executed.Nonchalant
J
1

I guess this library is the answer to your question

it tests all the bean's initial values, the setters, the getters, hashCode(), equals() and toString(). All you have to do is define a map of default and non default property/value.

It can also test objects that are beans with additional non default constructors.

Jughead answered 4/3, 2011 at 21:2 Comment(1)
It seems page is no longer available (404).Valuer
W
0

Answering the previous comment at @me here because of my reputation:

Vlookward, not writing getters/setters makes no sense at all. The only options for setting private fields is to have explicit setters, to set them in your constructor, or to set the indirectly via other methods (functionally deferring the setter to another place). Why not use setters?

Well, sometimes, there is no need to the field be private (Sorry if my English is not very good). Often, we write our software as it was a library and we encapsulate our fields (our business logic fields) with unnecessary getters/setters.

Other times, that methods are actually necessary. Then, there are two possibilities:
1. There is business logic inside them. Then they sould be tested, but they aren't real getters/setters. I always write that logic in other classes. And the tests test that other classes, not the POJO.
2. There is not. Then, do not write them by hand, if you can. For example, an implementation for the next interface may be fully autogenerated (and also in runtime!) :

interface NamedAndObservable {
  String getName();
  void setName(String name);
  void addPropertyChangeListener(PropertyChangeListener listener);
  void addPropertyChangeListener(String propertyName,
                                 PropertyChangeListener listener);
}

So test only what is written by hand. No matter if it is a getter/setter.

Wicketkeeper answered 22/9, 2008 at 10:23 Comment(0)
V
0

I don't write test cases for each property, but instead test all of the setters/getters in a single test case using reflection/introspector to determine the type(s). Here is a great resource that shows this:

http://www.nearinfinity.com/blogs/scott_leberknight/do_you_unit_test_getters.html

Verbiage answered 20/7, 2011 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.