Mockito: doReturn() vs when()

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;

public class MockitoTest {

    @Test
    public void test() {
        X x = spy(X.class);
        doReturn("ace").when(x).foo();        
        Assert.assertEquals(x.foo(), "ace");
    }

    @Test(expected = NullPointerException.class)
    public void test2() {
        X x = spy(X.class);

        /**
         * Using Mockito.when(...).thenReturn(...)
         * the real method will still be invoked !!!
         * NPE error because of y.bar() fall on null value in foo() method
         */
        when(x.foo()).thenReturn("ace");

        Assert.assertEquals(x.foo(), "ace");
    }   
}

class X {
    private Y y;
    public String foo() {
        return y.bar();
    }
}

class Y {
    public String bar() {
        return "Bar";
    }
}