最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

dependency injection - Mocking injected provided service in standalone angular component AND NOT IN ROOT for karma jasmine tests

programmeradmin2浏览0评论

FYI: I am using angular 19.1.0 with karma

Let's assume we have this service and component

// NOT PROVIDED IN ROOT!
@Injectable()
export class TestService {
  getData(): string {
    return 'this is real data'
  }
}
// Standalone component!
@Component({
  selector: 'app-root',
  templateUrl: './appponent.html',
  styleUrl: './appponent.scss',
  providers: [TestService]
})
export class AppComponent {
  service = inject(TestService)
}

As you noticed, the service is not provided in root but is provided in the component and injected as well. I noticed with this setting that i am not able to mock this service in the karma unit tests. I can see it has to do with the service being provided in the component, but i am not sure how i can fix it. Here is a snippet of the test.

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [{
        provide: TestService,
        useValue: {
          getData: () => ('mocked data'),
        }
      }]
    })pileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixtureponentInstance;

    expect(app).toBeTruthy();

    console.log(app.service.getData())
  });
});

I should expect here that app.service.getData() should log out "mocked data", however, i get "this is real data".

FYI: I am using angular 19.1.0 with karma

Let's assume we have this service and component

// NOT PROVIDED IN ROOT!
@Injectable()
export class TestService {
  getData(): string {
    return 'this is real data'
  }
}
// Standalone component!
@Component({
  selector: 'app-root',
  templateUrl: './appponent.html',
  styleUrl: './appponent.scss',
  providers: [TestService]
})
export class AppComponent {
  service = inject(TestService)
}

As you noticed, the service is not provided in root but is provided in the component and injected as well. I noticed with this setting that i am not able to mock this service in the karma unit tests. I can see it has to do with the service being provided in the component, but i am not sure how i can fix it. Here is a snippet of the test.

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [{
        provide: TestService,
        useValue: {
          getData: () => ('mocked data'),
        }
      }]
    })pileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixtureponentInstance;

    expect(app).toBeTruthy();

    console.log(app.service.getData())
  });
});

I should expect here that app.service.getData() should log out "mocked data", however, i get "this is real data".

Share edited Mar 7 at 19:57 Naren Murali 60.7k5 gold badges44 silver badges79 bronze badges asked Mar 7 at 18:05 Abdullah El-KindyAbdullah El-Kindy 731 silver badge5 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The component is not having the mocked service( might be because it was not provided in the root of the application ). So try the overrideProvider method to configure the mock service, this method works.

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [
        {
          provide: TestService,
          useValue: {
            getData: () => 'mocked data',
          },
        },
      ],
    })
    .overrideProvider(TestService, {          // <- changed here!
        useValue: {                           // <- changed here!
          getData: () => 'mocked data',       // <- changed here!
        },                                    // <- changed here!
    })                                        // <- changed here!
    pileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixtureponentInstance;

    expect(app).toBeTruthy();

    console.log(app.service.getData());
  });
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论