I'm trying to manipulate the service return value in my test and attach that value to components field.
So I mock myService
inside the Test1
and manipulate its value as true
so that it always returns true
. With the call fixture.detectChanges();
I invoke the this.myService.getProperty('param');
inside the PageComponent
which should return true
and make the value of myField
also true
. But it doesn't. The value of the field is still false
. Test1
fails ofcourse.
I don't undestand what happens. Why can I just define the return value true
inside the test and make the components value by that?
Test
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { anything, instance, mock, reset, verify, when } from 'ts-mockito';
import { MyService } from '../services/myservice.service';
describe('Test', () => {
let component: PageComponent;
let fixture: ComponentFixture<PageComponent>;
let myServiceMock: myService = mock(MyService);
describe('PageComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [PageComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: myService, useValue: instance(myServiceMock) },
]
}).compileComponents();
fixture = TestBed.createComponent(PageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(() => {
reset(myServiceMock);
});
it('Test1 - property should be true', () => {
when(myServiceMock.getProperty(anything())).thenReturn(true);
fixture.detectChanges();
verify(myServiceMock.getProperty(anything())).once();
expect(component.isCountryInfoVisible).toBeTrue();
// Test Failed
// Expected value to be true:
// true
// Received:
// false
});
});
});
PageComponent
export class PageComponent implements OnInit {
myField: boolean;
constructor(private myService: MyService) {}
ngOnInit(): void {
this.myField = this.myService.getProperty('param');
}
}
MyService
@Injectable()
export class MyService {
private properties: Map<string, string> = new Map<string, string>();
constructor() { }
public getProperty(key: string): string {
return this.properties.get(key);
}
....
}
Thanks to @EstusFlask I've figured out what happens;
My service call is inside
ngOnInit
which gets already invoked by the firstfixture.detectChanges();
. In that case the secondfixture.detectChanges();
doesn't have any effect at all because it never get invoked again.Solution: move the
when(myServiceMock.getProperty(anything())).thenReturn(true);
just above the firstfixture.detectChanges();
like: