Smokey Dawson
Smokey Dawson

Reputation: 9230

angular unit test function.pipe is not a function

I am aware there is a similar question here

but I am doing what the suggested answer says and I am still getting this error

basically I have a function like so

checkForInvitation() {
        this._join.joinInformationSource.pipe(filter(x => x !== null)).subscribe(result => {
            this.joinInformation = result;
            this.setFields(result.userInfo);
        });
    }

basically it gets information and then calls another method to prepopulate some form fields.

now I am trying to test this method so I have created a spy like so...

// ...

const joinServiceSpy = jasmine.createSpyObj('JoinService', ['joinInformationSource']);

// ...

providers: [
    { provide: JoinService, useValue: joinServiceSpy }
]

// ...

joinService = TestBed.get(JoinService);

it('should prepopulate fields if there is join information', () => {
   let joinInfoSpy = joinService.joinInformationSource.and.returnValue(
       of(
          // ... object
       )
   )
});

now when I run ng test I get this error repeatedly

this._join.joinInformationSource.pipe is not a function

this is my joinService

joinInformationSource = new BehaviorSubject<JoinInformation>(null);

setJoinInformation(joinInformation: JoinInformation) {
    this.joinInformationSource.next(joinInformation);
}

What am I doing wrong here??

Upvotes: 1

Views: 5147

Answers (1)

Ken Bekov
Ken Bekov

Reputation: 14015

According to the documentation createSpyObj accepts a list of methods as a second parameter. So when you're creating the mocking object, you create joinInformationSource as a function.

const joinServiceSpy = jasmine.createSpyObj('JoinService', ['joinInformationSource']);

//now joinSeverSpy contains method joinInformationSource

But in your code you use joinInformationSource as a field

// _join.joinInformationSource has been used as a field

this._join.joinInformationSource.pipe(filter(x => x !== null)).subscribe(result => {
    this.joinInformation = result;
    this.setFields(result.userInfo);
});

And since joinInformationSource is a function it definitely doesn't have a pipe method. There are few solutions. One of them is using of spyOnProperty method:

//create a service object and define a property

const joinService: any = new Object();
Object.defineProperty(joinService, 'joinInformationSource', {get: () => {}});

//then create a spy on the property

it('should prepopulate fields if there is join information', () => {
    let joinInfoSpy = spyOnProperty(joinService, 'joinInformationSource', 'get')
        .and.returnValue(
            new BehaviorSubject<JoinInformation>(//object)
        )
    }
    //the rest of the code
);

Upvotes: 2

Related Questions