I have the following functions:
function getPersonData(id) {
  retrieveData(
    id,
    function(person) {
      if(person.name) {
        displayPerson(person);
      }
    }
}
function retrieveData(id, successCallBack) {
    executeRequest(id, {
      success: successCallBack
    });
}
getPersonData retrieves a person's information based on the id. It in turn calls retrieveData by passing in the id and a successCallBack function. 
retrieveData takes the id and successCallBack and calls another function, executeRequest, which gets the data and passes back a person object.
I am trying to test getPersonData and have the following spec set up
describe("when getPersonData is called with the right person id", function() {
  beforeEach(function() {
    spyOn(projA.data, "retrieveData").and.returnValue(
      {
        'name': 'john'
      }
    );
    spyOn(projA.data, "displayPerson");
    projA.data.getPersonData("123");
  });
  it("displays the person's details", function() {
    expect(projA.data.displayPerson).toHaveBeenCalled();
  );
}); 
But when the spec is executed the displayPerson method isn't called. This is because the person data being passed back from the success callBack function(person) isn't being passed in even though I have mocked retrieveData to return a result.
My question is: Is this the right way to test callBack functions? Either way what am I doing wrong?
                        
Ok, so jasmine is tricky in a lot of subtle ways and I think there's two main issues with your code
retrieveDatafunction which just callsexecuteRequestfunction with the exact same parameters but in a slightly different way.I rewrote your getPersonData to be like this
2. In order to test asynchronous code in Jasmine, you need to include a
donecallback with the test. Also, if you expect a callback function to fire automatically, you need to set it up within asetTimeoutfunction, otherwise it will never fire. Here's an adjusted example: