0

Using GroovyTestCase, I need to test if a LinkedList's last node is what I intend it to be. I don't want to give this class a public accessor.


First some potentially useful information about my classes:

  • Node is a private subclass of LinkedList
  • LastNode is private
  • LinkedList is public and a .java file
  • LinkedListTest is a .groovy file

Here is an example:

class LinkedListTest extends GroovyTestCase
{
    // == -- TEST ADD AT LAST ELEMENT -- == //
    void testAdd_1Arg()
    {
        add1_entries_currently_in_the_list_are_unaffected ( )
        add1_lists_size_is_increased_by_1 ( )
        add1_adds_to_last_entry( )
    }

    void add1_adds_to_last_entry()
    {
        int size = 5;
        LinkedList<Object> linkedList = get_n_element_integerType_LinkedList ( size );
        linkedList.add ( -1 )
        // check if Instance variable LastNode.data == size+10
    } }

I marked the line where my question is specific to as // check if Instance variable LastNode.data == size+10.

PVNRT
  • 235
  • 1
  • 4
  • 14
  • Groovy does not respect private. This may be a bug or a design "feature", I'm not sure. You can directly access private members using groovy. – DwB Nov 06 '17 at 19:11
  • @DwB adding the line `assert linkedList.lastNode.data == -1` throws MissingPropertyException – PVNRT Nov 06 '17 at 19:18
  • Depending on how pedantic a point one wants to argue from, it could be said that Groovy respects `private` exactly as much as Java does. What appears to be Groovy's lack of respect is actually Groovy adding some syntactic sugar to the Java reflection API. See this: https://stackoverflow.com/questions/40929264/how-is-groovy-able-to-access-private-methods-of-a-java-class. Note that Groovy will not let you access the private field via Groovy's automated getter/setter methods because those methods are not automatically generated for private fields. – geneSummons Nov 06 '17 at 19:23
  • @PVNRT Is the `MissingPropertyException` related to `lastNode` or `data`? – Jeff Scott Brown Nov 06 '17 at 19:53
  • Based on @geneSummons 's answer, consider using reflection to access the private fields. There are many open source libraries that include reflection utilities (for example, Spring). Either use one of those libraries or write a utility that fits your problem. Just write the reflection utility in Java and use it in Groovy. – DwB Nov 06 '17 at 19:53
  • @DwB There really is no reason to do that. Since he is in a `GroovyTestCase` the code is written in Groovy and he can access the private member directly. – Jeff Scott Brown Nov 06 '17 at 19:54
  • "Note that Groovy will not let you access the private field via Groovy's automated getter/setter methods " - That is true, but you can access the field directly (not using getter/setter methods). – Jeff Scott Brown Nov 06 '17 at 19:56
  • See https://gist.github.com/jeffbrown/47233402cf23fef67c259f139fbb0a13 – Jeff Scott Brown Nov 06 '17 at 19:59
  • Of course the same would work if Widget were written in Groovy (or any other JVM language). – Jeff Scott Brown Nov 06 '17 at 20:03
  • 1
    UnitTests should verify *public observable behavior* of the code under test. The state of a private member is *implementation detail* and should not be tested at all. The reason is that you might want to change the implementation detail later without breaking the behavior. A proper unit test will detect if you changed the behavior accidentally. Your "detail test" needs to be changed too and cannot provide this protection. – Timothy Truckle Nov 08 '17 at 11:44
  • True, I have been told this concept before; however, in this case, I am noticed conflicting concept that is - a good unit test will test a single methods functionality and not rely on any other methods. So I am given the choice to access these private vars, or rely on another such as a `toArray` or `getElement` method to test the accuracy of `add`. I'm not sure what "rule" to break, what do you think? @TimothyTruckle – PVNRT Nov 10 '17 at 16:15
  • *"I am noticed conflicting concept that is - a good unit test will test a single methods functionality and not rely on any other methods."* This is not a conflict. It is a question of *what is a unit*. Usually (my) units have *one public method* that is tested directly and this is supported by a *bunch of private methods* contributing to the behavior. The latter are *implementation detail* that may change (even be extracted to other objects) without the the need to change any unit test. – Timothy Truckle Nov 10 '17 at 22:59

0 Answers0