首页 > 解决方案 > How to filter console.log when using Angular Karma Jasmine

问题描述

I am looking for a way to filter out which console logs are printed to the console when running tests. There are console logs that are very useful for the project to have, however when we run the tests they don't serve much help and bloat the output.

I have tried running this in our test.ts file (which used in out angular config file for compiling the tests), however it doesn't work.

//...
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.less"
            ],
            "scripts": [],
            "assets": [
              "src/assets",
              "src/.well-known"
            ]
          }
        },
//...
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import "zone.js/dist/zone-testing";
import { getTestBed } from "@angular/core/testing";
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing";

//...

//bug: this errors with Error: Spies must be created in a before function or a spec
spyOn(window.console, "log").and.callFake(() => {});

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
// Then we find all the tests.
const context = require.context("./", true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

I understand I can make a spy and import it into every test file, however we have a lot of them and this isn't really a scaleable approach.

Is there a way for me to spy on this for every test? In jest this is really easily achieved by using their setupFiles feature.

标签: angularunit-testingkarma-jasminekarma-runner

解决方案


I was able to solve by updating my test.ts to be:

// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import "zone.js/dist/zone-testing";
import { getTestBed } from "@angular/core/testing";
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing";

//...

//bug: this errors with Error: Spies must be created in a before function or a spec
spyOn(window.console, "log").and.callFake(() => {});

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
// Then we find all the tests.
const context = require.context("./", true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

beforeEach(() => {
  const ifTextMatchesThenIgnore = (text: string) => {
    return (
      text.toLowerCase().includes("configuring happyland") ||
      text.match(/^\[.*\]+/) ||
      text.toLowerCase().includes("stripe")
    );
  };
  spyOnConsole("log", ifTextMatchesThenIgnore);
});
const spyOnConsole = (property: "log" | "warn" | "info" | "error", ifTextMatchesThenIgnore: Function) => {
  const print = console[property];
  spyOn(console, property).and.callFake(function (...args) {
    let filteredArgs = [];
    for (let i = 0; i < args.length; i++) {
      const text = args?.[i];
      try {
        if (ifTextMatchesThenIgnore(text)) return;
      } catch {}
      filteredArgs.push(text);
    }
    if (filteredArgs.length > 0) {
      print(...filteredArgs);
    }
  });
};

推荐阅读