Skip to content

Commit

Permalink
test: use angular testing library for component tests (#732)
Browse files Browse the repository at this point in the history
* test: use angular testing library for component tests

- refactored 3 test as a start
- testing with actual (amqp) mock data

* test: add basic tests on the data displayed in the component
  • Loading branch information
timonback committed May 3, 2024
1 parent 011870b commit 9b6e34e
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 72 deletions.
@@ -1,45 +1,39 @@
/* SPDX-License-Identifier: Apache-2.0 */
import { AsyncApiService } from "../../../service/asyncapi/asyncapi.service";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { render, screen } from "@testing-library/angular";
import { ChannelMainComponent } from "./channel-main.component";
import { AsyncApiService } from "../../../service/asyncapi/asyncapi.service";
import { PublisherService } from "../../../service/publisher.service";
import { MatDivider } from "@angular/material/divider";
import { MatTab, MatTabGroup, MatTabHeader } from "@angular/material/tabs";
import { JsonComponent } from "../../json/json.component";
import { MaterialModule } from "../../../material.module";
import { MarkdownModule } from "ngx-markdown";
import {
mockedAsyncApiService,
mockedExampleSchemaMapped,
} from "../../../service/mock/mock-asyncapi.service";
import { MockAppJson, MockAppSchema } from "../../mock-components.spec";

describe("ChannelMainComponent", () => {
let component: ChannelMainComponent;
let fixture: ComponentFixture<ChannelMainComponent>;
const mockData = mockedExampleSchemaMapped.channelOperations[0];

let mockedAsyncApiService = {
getAsyncApi: jest.fn(),
};
let mockedPublisherService = {
getAsyncApi: jest.fn(),
};
beforeEach(async () => {
mockedAsyncApiService.getAsyncApi.mockClear();

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
MatDivider,
MatTabGroup,
MatTab,
MatTabHeader,
MarkdownModule.forRoot(),
],
declarations: [ChannelMainComponent, JsonComponent],
await render(ChannelMainComponent, {
imports: [MaterialModule, MarkdownModule.forRoot()],
declarations: [MockAppJson, MockAppSchema],
providers: [
{ provide: AsyncApiService, useValue: mockedAsyncApiService },
{ provide: PublisherService, useValue: mockedPublisherService },
{ provide: PublisherService, useValue: {} },
],
}).compileComponents();

fixture = TestBed.createComponent(ChannelMainComponent as any);
component = fixture.debugElement.componentInstance;
componentProperties: {
channelName: mockData.name,
operation: mockData.operation,
},
});
});

it("should create the component", () => {
expect(component).toBeTruthy();
it("should render the component and data", () => {
expect(
screen.getByText(mockData.operation.message.description)
).toBeTruthy();
});
});
Expand Up @@ -16,21 +16,20 @@ import { wrapException } from "../../../util/error-boundary";
styleUrls: ["./channel-main.component.css"],
})
export class ChannelMainComponent implements OnInit {
@Input() docName: string;
@Input() channelName: string;
@Input() operation: Operation;

schema: Schema;
schemaIdentifier: string;
defaultExample: Example;
defaultExampleType: string;
exampleTextAreaLineCount: number;
exampleTextAreaLineCount: number = 1;
headers: Schema;
headersSchemaIdentifier: string;
headersExample: Example;
headersTextAreaLineCount: number;
headersTextAreaLineCount: number = 1;
messageBindingExample?: Example;
messageBindingExampleTextAreaLineCount: number;
messageBindingExampleTextAreaLineCount: number = 1;

constructor(
private asyncApiService: AsyncApiService,
Expand All @@ -47,17 +46,17 @@ export class ChannelMainComponent implements OnInit {
this.schema = schemas.get(this.schemaIdentifier);

this.defaultExample = this.schema.example;
this.exampleTextAreaLineCount = this.defaultExample?.lineCount || 0;
this.exampleTextAreaLineCount = this.defaultExample?.lineCount || 1;
this.defaultExampleType = this.operation.message.name;

this.headersSchemaIdentifier = this.operation.message.headers.name.slice(
this.operation.message.headers.name.lastIndexOf("/") + 1
);
this.headers = schemas.get(this.headersSchemaIdentifier);
this.headersExample = this.headers.example;
this.headersTextAreaLineCount = this.headersExample?.lineCount || 0;
this.headersTextAreaLineCount = this.headersExample?.lineCount || 1;
this.messageBindingExampleTextAreaLineCount =
this.messageBindingExample?.lineCount || 0;
this.messageBindingExample?.lineCount || 1;
});
}

Expand Down
Expand Up @@ -36,7 +36,6 @@ <h3>{{ channel.name }}</h3>
<app-channel-main
[channelName]="channel.name"
[operation]="channel.operation"
[docName]="docName"
>
</app-channel-main>
</mat-expansion-panel>
Expand Down
@@ -1,31 +1,35 @@
/* SPDX-License-Identifier: Apache-2.0 */
import { AsyncApiService } from "../../service/asyncapi/asyncapi.service";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { render, screen } from "@testing-library/angular";
import { ChannelsComponent } from "./channels.component";
import { MatAccordion } from "@angular/material/expansion";
import { AsyncApiService } from "../../service/asyncapi/asyncapi.service";
import {
mockedAsyncApiService,
mockedExampleSchemaMapped,
} from "../../service/mock/mock-asyncapi.service";
import { MaterialModule } from "../../material.module";
import { MockChannelMainComponent } from "../mock-components.spec";

describe("ChannelsComponent", () => {
let component: ChannelsComponent;
let fixture: ComponentFixture<ChannelsComponent>;

let mockedAsyncApiService = {
getAsyncApi: jest.fn(),
};
beforeEach(async () => {
mockedAsyncApiService.getAsyncApi.mockClear();

beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatAccordion],
declarations: [ChannelsComponent],
await render(ChannelsComponent, {
imports: [MaterialModule],
declarations: [MockChannelMainComponent],
providers: [
{ provide: AsyncApiService, useValue: mockedAsyncApiService },
],
}).compileComponents();

fixture = TestBed.createComponent(ChannelsComponent as any);
component = fixture.debugElement.componentInstance;
});
});

it("should create the component", () => {
expect(component).toBeTruthy();
it("should render the component and data", () => {
expect(screen.getByText("Channels")).toBeTruthy();

mockedExampleSchemaMapped.channelOperations.forEach((channelOperation) => {
expect(screen.getAllByText(channelOperation.name)[0]).toBeTruthy();
expect(
screen.getAllByText(channelOperation.operation.message.title)[0]
).toBeTruthy();
});
});
});
Expand Up @@ -15,7 +15,6 @@ import { Location } from "@angular/common";
export class ChannelsComponent implements OnInit {
channels: ChannelOperation[];
selectedChannel: string;
docName: string;

constructor(
private asyncApiService: AsyncApiService,
Expand Down
29 changes: 29 additions & 0 deletions springwolf-ui/src/app/components/mock-components.spec.ts
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: Apache-2.0 */
import { Component, Input } from "@angular/core";
import { Schema } from "../models/schema.model";
import { Operation } from "../models/operation.model";

/*
* This file contains all mock components for usage in tests.
*/
describe("MockTest", () => {
it("basic test, since at least one test is required 1 + 1 = 2", () => {
expect(1 + 1).toBe(2);
});
});

@Component({ selector: "app-json", template: "" })
export class MockAppJson {
@Input() data: any;
}

@Component({ selector: "app-schema", template: "" })
export class MockAppSchema {
@Input() schema: Schema;
}

@Component({ selector: "app-channel-main", template: "" })
export class MockChannelMainComponent {
@Input() channelName: string;
@Input() operation: Operation;
}
33 changes: 19 additions & 14 deletions springwolf-ui/src/app/components/servers/servers.component.spec.ts
@@ -1,27 +1,32 @@
/* SPDX-License-Identifier: Apache-2.0 */
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { render, screen } from "@testing-library/angular";
import { ServersComponent } from "./servers.component";
import { AsyncApiService } from "../../service/asyncapi/asyncapi.service";
import {
mockedAsyncApiService,
mockedExampleSchemaMapped,
} from "../../service/mock/mock-asyncapi.service";
import { MaterialModule } from "../../material.module";

describe("ServerComponent", () => {
let component: ServersComponent;
let fixture: ComponentFixture<ServersComponent>;
mockedAsyncApiService.getAsyncApi.mockClear();

let mockedAsyncApiService!: { getAsyncApi: jest.Mock };

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ServersComponent],
beforeEach(async () => {
await render(ServersComponent, {
imports: [MaterialModule],
providers: [
{ provide: AsyncApiService, useValue: mockedAsyncApiService },
],
}).compileComponents();

fixture = TestBed.createComponent(ServersComponent as any);
component = fixture.debugElement.componentInstance;
});
});

it("should create the component", () => {
expect(component).toBeTruthy();
it("should render the component and data", () => {
expect(screen.getByText("Servers")).toBeTruthy();

mockedExampleSchemaMapped.servers.forEach((server, key) => {
expect(screen.getAllByText(key)[0]).toBeTruthy();
expect(screen.getAllByText(server.protocol)[0]).toBeTruthy();
expect(screen.getAllByText(server.host)[0]).toBeTruthy();
});
});
});
15 changes: 15 additions & 0 deletions springwolf-ui/src/app/service/mock/mock-asyncapi.service.ts
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: Apache-2.0 */
import { of } from "rxjs";
import { AsyncApiMapperService } from "../asyncapi/asyncapi-mapper.service";
import { exampleSchemas } from "./example-data";

const asyncApiMapperService = new AsyncApiMapperService({
showError: jest.fn(),
showWarning: jest.fn(),
});
export const mockedExampleSchemaMapped = asyncApiMapperService.toAsyncApi(
exampleSchemas[0].value
);
export const mockedAsyncApiService: { getAsyncApi: jest.Mock } = {
getAsyncApi: jest.fn().mockReturnValue(of(mockedExampleSchemaMapped)),
};

0 comments on commit 9b6e34e

Please sign in to comment.