question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot mock providedIn:'root' service

See original GitHub issue

Hi, I am not able to use that awesome tool, due to that issue 😦

How to reproduce

I’ve used code from your examples and extended it with my use-case.

https://stackblitz.com/github/getsaf/shallow-render-stackblitz?file=examples%2Fcomponent-with-service.spec.ts

In file component-with-service.spec.ts you can paste next code:

import { Component, Injectable, NgModule } from '@angular/core';
import { Shallow } from 'shallow-render';

////// Module Setup //////
@Injectable({
  providedIn: 'root'
})
class ColorService {
  red() {
    return "RED";
  }
  blue() {
    return "BLUE"
  }
}

@Injectable({
  providedIn: 'root'
})
class RedService {
  constructor(private serv: ColorService) {}

  color() {
    return this.serv.red();
  }
}

@Component({
  selector: 'color-label',
  template: '<label>{{redService.color()}}</label>',
})
class ColorLabelComponent {
  constructor(public redService: RedService) {}
}

@NgModule({
  declarations: [ColorLabelComponent],
})
class ColorModule {}
//////////////////////////

describe('component with service', () => {
  let shallow: Shallow<ColorLabelComponent>;

  beforeEach(() => {
    shallow = new Shallow(ColorLabelComponent, ColorModule)
      .mock(RedService, {color: () => 'MOCKED COLOR'});
  });

  it('Uses the color from the RedService', async () => {
    const {element} = await shallow.render();

    expect(element.nativeElement.innerText).toBe('MOCKED COLOR');
  });
});

Actual result

Ran 1 of 40 specs - run all1 spec, 1 failure, randomized with seed 62283Spec List | Failures
component with service > Uses the color from the RedService
Expected 'RED' to be 'MOCKED COLOR'.

Expected result

Test passed

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
getsafcommented, Aug 19, 2019

Ok, I see what you’re getting at now. I may look into your suggestion to modify the mock method to use overrideProvider. I didn’t even realize that root providers worked with TestBed until this example 😃

1reaction
getsafcommented, Aug 19, 2019

Oh, in the mean-time you may use the provideMock or alwaysProvideMock feature to mock these things out in your tests with a one-liner.

edit: The more I think about it, this actually seems like the preferred way to deal with root providers. Shallow cannot automatically mock root providers because Angular does not expose a list of the providers marked as such. That being the case, it’s up to the tester to provide mocks for these manually and the simplest way to do this would be to use provideMock.

I will still do some research to see if I can extract a list of all the available root-providers. I don’t know if Angular supports this but I could potentially “hook” into the Injectable decorator and track them myself. Would rather Angular expose a method that lets me fetch them but we’ll see how it works out. If I can get this working, then shallow-render will support auto-mocking these services.

Read more comments on GitHub >

github_iconTop Results From Across the Web

providedIn: 'root' automatically declare services for testing
All the services registered with providedIn aren't loaded in the test, they are instantiated lazily, only when they are really needed.
Read more >
How to mock providers in Angular tests
A mock provider in Angular tests can be created by MockProvider function. The function supports services and tokens.
Read more >
How to mock a queryParam for a service testing in Angular?
I am trying to test an observable from a service in Angular, which depends ... Observable } from 'rxjs'; @Injectable({ providedIn: 'root', }) ......
Read more >
Testing Dependency Injection • Angular - codecraft.tv
Your browser can't play this video. ... Let's imagine we have a mock AuthService like so: ... auth.service"; class MockAuthService extends AuthService ...
Read more >
How I Write Marble Tests For RxJS Observables In Angular
user.service'@Injectable({ providedIn: 'root',})export class ... Basic idea is to mock the public observables from the provided services and test our ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found