0

I've got following class

import com.model.domain.Node;

public class Linker {
    public void link(Node node){
        node = Node.findById(node.getId());

        if(node.getLinkedNode() == null)
            return;
    }
}

and unit test for it

import static org.junit.Assert.*;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.when;

import com.model.domain.Node;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Node.class})
public class LinkerTest {

    private Linker linker = new Linker();

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(Node.class);
    }

    @Test
    public void testLink() throws Exception {
        Node node = new Node();
        node.setId(123456L);

        Node foundNode = new Node();
        foundNode.setId(1234L);
        foundNode.setName("FounNode");

        when(Node.findById(anyLong())).thenReturn(foundNode);

        linker.link(node);

        assertEquals(node, foundNode);
    }
}

now, my problem is that in the testLink test, I would expect object nodes reference to point to foundNode object after line linker.link(node); is executed as link method changes the reference to the object.

However, that is not the case. in the Linker#link method the reference is correctly updated but after the return in LinkerTest#testLink method the reference is still the original one and the assertion fails.

Any ideas? Thanks

rojanu
  • 1,592
  • 5
  • 20
  • 34
  • 1
    You know that Java only [passes by value](http://stackoverflow.com/q/40480/1426891), right? You can pass references to objects, and those objects may be modified in the method, but the variable at the call site will never _refer to a different instance_ due only to a method call. – Jeff Bowman Jun 01 '15 at 17:02
  • Thanks for the wake up call – rojanu Jun 02 '15 at 08:02

1 Answers1

1

Java only passes by value. You can pass references to objects, and those objects may be modified in the method, but the variable at the call site will never refer to a different instance due only to a method call.

One way around this is to pass in an object that wraps a reference:

class Holder {
  Node node;
}

...so the reference to Holder stays constant but the field it contains may change. If possible, though, prefer to return a value rather than mutating state, which will likely also make your class easier to test.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251