Angular — the JavaScript framework that developers love to hate — has changed quite substantially since its AngularJS days. Even though we typically prefer to use React at Atomic for a number of reasons, we do occasionally have an Angular project or two come our way.
Personally, I’m not thrilled to be working with Angular instead of React. But, when I end up on one of these projects, I use a few methods to improve the Angular development experience.
Angular Project Technique #1: Update Test Infrastructure
When creating a new Angular project using the Angular CLI, it adds configuration to use Jasmine/Karma for running unit tests. Jasmine provides a way to write unit tests as specs and comes with a variety of built-in matchers for assertions. However, I prefer to use Jest for a number of reasons:
- Tests run in parallel and often faster.
- Tests run in terminal by default, with no browser required.
- Creating mock objects and controlling their behavior on a per-test basis is easy.
There are a few packages that help set up Jest in an Angular project. These include instructions for configuring Jest and removing Jasmine. Installing these packages and following their setup instructions should be all you need to get started with Jest in an Angular project:
For end-to-end tests, Angular projects typically use the Protractor package to facilitate user interactions in the browser. This appears to be changing in newer versions of Angular, which means this is a perfect time to switch to something like Cypress for your end-to-end tests!
The Cypress team maintains an Angular schematic to help get you started.
Angular Project Technique #2: Improving Reactive Forms
If you’re building a website that requires retrieving input from the user, you’ll likely need to use the ReactiveFormsModule. One of the main issues I have with Reactive Forms is that they don’t provide a way to define a type signature for the shape of the form’s data. Because of this, the form fields are treated as the any type and are often more difficult to work with.
When using the angular-typesafe-reactive-forms-helper package, we now have access to classes such as FormGroupTypeSafe<MyFormModel>
that accept generic types where we can specify the shape of the data in the form. This really comes in handy when trying to patch form values and avoid spelling mistakes in component templates.
Angular Project Technique #3: Shallow Render Components in Unit Tests
My biggest complaint when working on an Angular project is the need to manually configure the TestBed of every component test suite. This tedious task introduces a lot of busy work without providing a lot of benefit. Because of this, I decided to add shallow-render to my latest Angular project.
Shallow-render does as its name suggests, creating a shallow render of the component under test. Instead of a manually configured TestBed, the Shallow object takes an Angular module as a parameter in order to render the component. This greatly reduces the amount of required boilerplate to set up unit tests. Additionally, it verifies that your real module is configured correctly in order to render this component.
describe("My Component Tests", () => {
let shallow: Shallow<MyComponent>;
let serviceMock = {
getData: jest.fn();
};
beforeEach(async() => {
shallow = new Shallow(MyComponent, AppModule)
.mock(MyService, serviceMock);
});
it('should create', async () => {
const { instance } = await shallow.render();
expect(instance).toBeTruthy();
});
});
There is one caveat when using this package though. If you’re like me and register everything in your AppModule
until it becomes a problem, this package should help detect that problem early.
Shallow-render creates mocks for everything in the module for each test. This will start to slow down your tests quite a bit as your AppModule
gets bigger with each new component/service/module added to it. When this starts to happen, you should consider splitting your AppModule
into separate feature modules as recommended in the Angular docs.
Improving Your Angular Project
Do I enjoy using Angular now that I have found some packages that make the experience a little better? Not really, but I do appreciate the benefits I have noticed by introducing these packages to my latest Angular project.
Do you have recommendations for some useful Angular packages? Please share it by commenting below!