简体   繁体   English

无法使用控制台构造函数参数测试 Angular 服务

[英]Unable to test Angular service with Console constructor parameter

I am trying to implement a logging service as the name service implies.我正在尝试实现名称服务所暗示的日志记录服务。 A concrete implementation of the logging service will be resolved at initialization time.日志服务的具体实现将在初始化时解决。 This concrete implementation is using the console to log the messages.这个具体的实现是使用控制台来记录消息。 I need the Console in the constructor to be able to mock it without affecting the global console object.我需要构造函数中的Console能够在不影响全局console对象的情况下模拟它。

I had the same test run on Jasmine and it would pass just fine.我在 Jasmine 上进行了相同的测试,它会通过的很好。 Also it works fine in the application, so I think it has something to do with Jest or its configuration.它在应用程序中也运行良好,所以我认为它与 Jest 或其配置有关。

I am trying to inject the Console interface into my Angular service like this:我正在尝试将控制台接口注入到我的 Angular 服务中,如下所示:

export class ConsoleLoggerService implements LoggerService {
   constructor(public console: Console) { }
}

When I try to run my test:当我尝试运行我的测试时:

describe('ConsoleLoggerService', () => {
  let service: ConsoleLoggerService;
  let consoleMock: Console;

  beforeEach(async(() => {
    consoleMock = {
      log(message?: any, ...optionalParams: any[]) { }
    } as Console;
    service = new ConsoleLoggerService(consoleMock);
  }));
  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

I get this error我收到这个错误

  ● Test suite failed to run

    ReferenceError: Console is not defined

       9 | export class ConsoleLoggerService implements LoggerService {
      10 |
    > 11 |   constructor(public console: Console) { }
         |                               ^

In my understanding the Console interface comes from @types/node and should be available globally.在我的理解中, Console接口来自@types/node并且应该在全球范围内可用。 Why does my test fail then?为什么我的测试失败了?

I am using Angular 9, Jest 24.9 and Nx 9 for my workspace.我的工作区使用的是 Angular 9、Jest 24.9 和 Nx 9。

If you want to test that console log was hit use jest to mock it.如果您想测试控制台日志是否被点击,请使用 jest 来模拟它。 In your test you could do something like this:在您的测试中,您可以执行以下操作:

it('console.log the text "hello"', () => {
  console.log = jest.fn();

  // call some function here that will end up doing your logging

  // The first argument of the first call to the function was 'hello'
  expect(console.log.mock.calls[0][0]).toBe('hello');
});

If you're just injecting it like that for testing purposes I would recommend just using jest to mock it like above.如果你只是为了测试目的而注入它,我会建议你像上面一样使用 jest 来模拟它。

If you have to keep injecting it like that you can use the testbed to provide a fake provider:如果您必须像这样继续注入它,您可以使用测试平台来提供一个虚假的提供者:

beforeEach(() => {
    TestBed.configureTestingModule({
        // MockConsole would be some fake class that you create
        providers: [{provide: Console, useClass: MockConsole }]
    });
    service = TestBed.get(CgonsoleLoggerService);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM