Angular Unit Test with Karma - Component under test is not rendered in browser

Viewed 566

I am currently trying to write unit tests for an Angular project using the latest version of Angular. I encountered the problem that the component is not rendered in the test browser (Chrome). After searching for hours and trying to mess with the configuration I decided to take a step back and compare the current project with a legacy project. I tested both projects on the same machine and the older version is working as expected. Downgrading the dependencies (Karma, Jasmine) is not an option because the latest Angular version apparently requires higher versions (I have not found any documentation for this).

As a last option I decided to generate a clean project (Angular CLI 12.2.6) and compare it with an online tutorial (Example tutorial for comparison). The problem remains. No output is rendered in the browser apart from the test results being reported.

Missing Template Render

What makes things even more confusing is that the output is visible during debugging:

enter image description here

Question

How can I achieve that the current component under test is rendered in the test browser?

I think I am missing something obvious here. Also clicking the debug button in the test browser shows "%X_UA_COMPATIBLE%" if this may be related to the problem. A quick online search did not result in anything useful.

Any help on this problem is appreciated.

Adding the test code below if needed:

Dependencies (Default CLI v12.2.6)

"dependencies": {
    "@angular/animations": "~12.2.0",
    "@angular/common": "~12.2.0",
    "@angular/compiler": "~12.2.0",
    "@angular/core": "~12.2.0",
    "@angular/forms": "~12.2.0",
    "@angular/platform-browser": "~12.2.0",
    "@angular/platform-browser-dynamic": "~12.2.0",
    "@angular/router": "~12.2.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.2.6",
    "@angular/cli": "~12.2.6",
    "@angular/compiler-cli": "~12.2.0",
    "@types/jasmine": "~3.8.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~3.8.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.3.5"
  }

Karma Config (Default apart from custom launcher):

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      jasmine: {
        // you can add configuration options for Jasmine here
        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
        // for example, you can disable the random execution with `random: false`
        // or set a specific seed with `seed: 4321`
      },
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    jasmineHtmlReporter: {
      suppressAll: true // removes the duplicated traces
    },
    coverageReporter: {
      dir: require('path').join(__dirname, './coverage/unit-testing'),
      subdir: '.',
      reporters: [
        { type: 'html' },
        { type: 'text-summary' }
      ]
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['ChromeDebug'],
    customLaunchers: {
      ChromeDebug: {
        base: "Chrome",
        flags: [
          "--remote-debugging-port=9333",
        ],
        debug: true,
      },
    },
    singleRun: false,
    restartOnFileChange: true
  });
};

Template

<p>pizza works!</p>

<p>{{toShowInTest}}</p>

Component

@Component({
  selector: 'app-pizza',
  templateUrl: './pizza.component.html',
  styleUrls: ['./pizza.component.css']
})
export class PizzaComponent implements OnInit {

  toShowInTest = "Pizza <3"

  constructor() { }

  ngOnInit(): void {
  }

}

Test


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

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [PizzaComponent],
    }).compileComponents();
  });

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should love pizza', () => {
    expect(component.toShowInTest).toBe('Pizza <3');

    component.toShowInTest = 'I love Pizza!';
    fixture.detectChanges();

    const container = fixture.debugElement.queryAll(By.css('p'))[1];
    expect(container.nativeElement.textContent).toBe('I love Pizza!');
  });
});

1 Answers

I guess toShowInTest should be marked by @Input() decorator

 @Input() toShowInTest = "Pizza <3";
Related