FluffySpoon.JavaScript.Testing.Faking: Unable to use mocks with angular TestBed

Love the simplicity of lib but im unable to use it in component testing with angular TestBed.

Test:

describe('FilterContentWidgetComponent', () => {
    let component: FilterContentWidgetComponent;
    let fixture: ComponentFixture<FilterContentWidgetComponent>;

    let filterMapperMock = Substitute.for<FilterMapper>();
    
    beforeEach(async() => {
        TestBed.configureTestingModule( {
            declarations: [ 
                FilterContentWidgetComponent,
            ],
            imports: [ HttpModule], 
            providers: [ 
                { provide: FilterMapper, useValue: <FilterMapper>filterMapperMock},
                
             ]
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(FilterContentWidgetComponent);
        component = fixture.componentInstance;
      });

    it('should create', () => {
        fixture.detectChanges();

        expect(component).toBeTruthy();
    });
});

Not sure if am doing sth wrong but i get following exception.

TypeError: Cannot convert object to primitive value at JitEmitterVisitor._emitReferenceToExternal (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4693:44) at JitEmitterVisitor.visitExternalExpr (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4662:1) at ExternalExpr.visitExpression (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:1293:1) at visitAllObjects.expr (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4387:1) at JitEmitterVisitor.visitAllObjects (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4406:1) at JitEmitterVisitor.visitAllExpressions (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4387:1) at JitEmitterVisitor.visitInvokeFunctionExpr (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4218:1) at JitEmitterVisitor.visitInvokeFunctionExpr (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4547:1) at InvokeFunctionExpr.visitExpression (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:1250:1) at visitAllObjects.expr (http://localhost:9876/node_modules/@angular/compiler/fesm2015/compiler.js?:4387:1)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 15 (10 by maintainers)

Most upvoted comments

I got a workaround that allows to inject substitutes as providers using the TestBed.

Defining the substitute provider resolution by value (‘useValue’) like this does not work indeed:

//
// Not working example because the provider is resolved by 'useValue'
//
describe('My test', () => {
  let sampleListService: SubstituteOf<SampleListService>();

  beforeEach(() => {
      sampleListService = Substitute.for<SampleListService>();

      TestBed.configureTestingModule({
        declarations: [ SampleListComponent ],
        providers: [
            { provide: SampleListService, useValue: sampleListService }
        ]
      })
      .compileComponents();
    });
});

But… what works is to setup the provider resolution by factory like that:

//
// Working example because the provider is resolved by 'useFactory'
//
describe('My test', () => {
  let sampleListService: SubstituteOf<SampleListService>();

  beforeEach(() => {
      sampleListService = Substitute.for<SampleListService>();

      TestBed.configureTestingModule({
        declarations: [ SampleListComponent ],
        providers: [
            { provide: SampleListService, useFactory: () => sampleListService }
        ]
      })
      .compileComponents();
    });
});

For the sake of brievety:

Replace

{ provide: SampleListService, useValue: sampleListService }

By

{ provide: SampleListService, useFactory: () => sampleListService }

And it should work. I’m using Jest as test framework with Angular 7.

Hope it helps !

It sure does @Karql! I’ll take a look as soon as I have the time. Won’t be for the next month or so I think.

I think I’ll end up creating different integrations for substitute.js, for instance @fluffy-spoon/substitute-angular, which you can then “hook in” to substitute.js to support these cases.

Sure here is isolated example

Its ng new with 3 files: foo-component.ts foo-service.ts foo-component.spec.ts

Sample.zip