Search code examples
javascriptangularunit-testingjasmineangular-unit-test

Angular Unit Test: How to mock properties in a method?


Here is the service that I am trying to test:

@Injectable()
export class BomRevisiosnsService {
    constructor(
        private baseService: BaseService,
        private appConstants: AppConstants,
        private dmConstants: DMConstants
    ) { }

    public getRevisionsData(): any {
        var itemId = this.appConstants.userPreferences.modelData['basicDetails']['itemId'];
        let url = this.dmConstants.URLs.GETBOMREVISIONS + itemId + "/GetRevisionsAsync";
        let headers = {
            "Content-Type": "application/json",
            UserExecutionContext: JSON.stringify(this.appConstants.userPreferences.UserBasicDetails),
        }
        if (itemId != null || itemId != undefined) {
            return this.baseService.getData(url, headers).map(response => {
                return response;
            });
        }
    }
}

spec file

describe('bom-revisions.service ',()=>{
    let bomRevisiosnsService:BomRevisiosnsService;
    let  baseService: BaseService;
    let  appConstants: AppConstants;
    let  dmConstants: DMConstants;
    beforeEach(()=>{
        baseService=new BaseService(null,null);
        appConstants=null;
        dmConstants=null;
        bomRevisiosnsService=new BomRevisiosnsService(baseService,appConstants,dmConstants);
    });
it('getRevisionsData() call base service getData()',()=>{
    let spy = spyOn(baseService, 'getData').and.returnValue(Observable.of())  
    bomRevisiosnsService.getRevisionsData();
    expect(baseService.getData).toHaveBeenCalled();
});

})

Error: TypeError: Cannot read property 'userPreferences' of null

I believe I need to provide some mock value for this.appConstants.userPreferences.modelData['basicDetails']['itemId']; and this.dmConstants.URLs.GETBOMREVISIONS + itemId + "/GetRevisionsAsync";


Solution

  • Yes, indeed, you need to provide a valid value for appConstants and dmConstants because the call to bomRevisiosnsService.getRevisionsData() uses that information internally.

    So, instead of assigning null to appConstants and dmConstants, you could create an objects with some valid data, like this:

    appConstants = {
      userPreferences: {
        modelData: {
          basicDetails: {
            itemId: 3 // some other valid value here is fine
          }
        },
        UserBasicDetails: {
          // some valid values here, maybe
        }
      }
    };
    
    dmConstants = {
      URLs: {
        GETBOMREVISIONS: 'revisions' // or just some valid value according to the use case
      }
    };
    

    And the same goes to baseService.

    In general, you need to create valid stub, mock, etc for all object, services, etc that are used internally by the service you're testing.