https://github.com/bobbyg603/ng-testing-tips-ng-mocks
Companion repo with ng-mocks examples
https://github.com/bobbyg603/ng-testing-tips-ng-mocks
angular how-to mocking ng-mocks testing tutorial
Last synced: 24 days ago
JSON representation
Companion repo with ng-mocks examples
- Host: GitHub
- URL: https://github.com/bobbyg603/ng-testing-tips-ng-mocks
- Owner: bobbyg603
- Created: 2023-02-27T17:41:25.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2023-03-19T22:44:00.000Z (about 3 years ago)
- Last Synced: 2025-11-10T22:16:30.749Z (7 months ago)
- Topics: angular, how-to, mocking, ng-mocks, testing, tutorial
- Language: TypeScript
- Homepage: https://bobbyg603.medium.com/angular-testing-tips-ng-mocks-7d9300443a9c
- Size: 234 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

# Angular Testing Tips: Ng-Mocks
This repo demonstrates how to use the [ng-mocks](https://ng-mocks.sudo.eu/) and [jasmine-auto-spies](https://www.npmjs.com/package/jasmine-auto-spies) to write better Angular unit tests. A companion article for this repo can be found on Medium.
## Steps 🥾
Clone or fork this repo
```bash
git clone https://github.com/bobbyg603/ng-testing-tips-ng-mocks
```
Install the dependencies
```bash
cd ng-testing-tips-ng-mocks && npm i
```
Run the sample application
```bash
npm run start
```
Run the tests
```bash
npm test
```
## Examples 🧑🏫
Using [MockComponent](https://ng-mocks.sudo.eu/api/MockComponent), we can easily declare fake components with all the propert `inputs` and `outputs` and use them in our tests.
[app.component.spec.ts@536ef8d](https://github.com/bobbyg603/ng-testing-tips-ng-mocks/blob/536ef8d19be9be22a3e0b267ec315ea27cd49ba1/src/app/app.component.spec.ts#L32C8-L36)
```ts
declarations: [
AppComponent,
MockComponent(FormComponent),
MockComponent(CardComponent)
],
```
Declaring mocked providers is also easy to do with the help of MockProvider.
[app.component.spec.ts@536ef8d](https://github.com/bobbyg603/ng-testing-tips-ng-mocks/blob/536ef8d19be9be22a3e0b267ec315ea27cd49ba1/src/app/app.component.spec.ts#L37-L39)
```ts
providers: [
MockProvider(DogService, dogService)
]
```
Ditto for [MockModule](https://ng-mocks.sudo.eu/api/MockProvider).
[app.component.spec.ts@536ef8d](https://github.com/bobbyg603/ng-testing-tips-ng-mocks/blob/536ef8d19be9be22a3e0b267ec315ea27cd49ba1/src/app/app.component.spec.ts#L27-L31)
```ts
imports: [
MockModule(FontAwesomeModule),
MockModule(MatProgressSpinnerModule),
MockModule(MatToolbarModule)
],
```
We can actually forgo all this noise by using [MockBuilder](https://ng-mocks.sudo.eu/api/MockBuilder).
[app.component.ts](https://github.com/bobbyg603/ng-testing-tips-ng-mocks/blob/578b2d7602b3eb17fb749c918033514e7665af3b/src/app/app.component.spec.ts#L30-L37)
```ts
await MockBuilder(AppComponent, AppModule)
.mock(FontAwesomeModule)
.mock(MatProgressSpinnerModule)
.mock(MatToolbarModule)
.mock(CardComponent)
.mock(DialogComponent)
.mock(FormComponent)
.provide({ provide: DogService, useValue: dogService });
```
[MockRender](https://ng-mocks.sudo.eu/api/MockRender) can be used as a drop in replacement for TestBed, and is super helpful for rendering custom templates and testing directives. For more information on `MockRender` see the companion article.
We can use [find](https://ng-mocks.sudo.eu/api/ngMocks/find), [findAll](https://ng-mocks.sudo.eu/api/ngMocks/findAll), [detectChanges](https://ng-mocks.sudo.eu/api/MockRender#testing-changedetectionstrategyonpush), [componentInstance](https://angular.io/guide/testing-components-basics#componentfixture), [nativeElement](https://angular.io/guide/testing-components-basics#nativeelement), and [querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) to help us run expectations against child component [inputs and outputs](https://angular.io/guide/inputs-outputs).
[app.component.ts](https://github.com/bobbyg603/ng-testing-tips-ng-mocks/blob/578b2d7602b3eb17fb749c918033514e7665af3b/src/app/app.component.spec.ts#L88-L137)
```ts
describe('template', () => {
beforeEach(() => {
rendered.detectChanges();
cardComponents = ngMocks.findAll(CardComponent).map(c => c.componentInstance);
formComponent = ngMocks.find('app-form').componentInstance;
});
it('should render title', () => {
expect(rendered.nativeElement.querySelector('span.title')?.textContent).toMatch(app.title);
});
it('should pass breed to form', () => {
expect(formComponent.breed).toBe(app.breed);
});
it('should pass breeds to form', () => {
expect(formComponent.breeds).toBe(breeds);
});
it('should pass count to form', () => {
expect(formComponent.count).toBe(app.count);
});
it('should create card for each dog', () => {
dogs.forEach(dog => {
expect(cardComponents.find(c => c.imgSrc === dog)).toBeTruthy();
});
});
it('should show spinner when loading', () => {
rendered.componentInstance.loading$ = of(true);
rendered.detectChanges();
expect(ngMocks.find(MatProgressSpinner)).toBeTruthy();
});
it('should not show spinner when not loading', () => {
rendered.componentInstance.loading$ = of(false);
rendered.detectChanges();
expect(ngMocks.findAll(MatProgressSpinner).length).toBe(0);
});
it('should call onFormChange when form component raises formChange event', () => {
const event = { breed: 'affenpinscher', count: 3 };
const spy = spyOn(rendered.componentInstance, 'onFormChange');
formComponent.formChange.emit(event);
expect(spy).toHaveBeenCalledWith(event);
});
});
```
If you found this repo valuable please subscribe to [@bobbyg603 on Medium](https://medium.com/@bobbyg603) for more Angular tips and tricks.
Thanks for reading!