More on Testing Cloud Apps
In a previous blog post, we learned how to get started with testing Cloud Apps. Since Cloud Apps are written in Angular, they can be tested using the standard toolset, including Jasmine and Karma. Like with any code project, an automated test suite helps to improve quality and prevent regressions, allowing us to make changes in the future with more confidence.
In this post, we’ll implement tests for the main component in the scaffolding provided with a newly initialized Cloud App. By doing so, we’ll learn a bit more about testing Cloud Apps, and pick up a few tips along the way.
Looking at the scaffolding, we see that provides some basic functionality that exercises some core Cloud App API features. Thinking of test cases, we came up with the following. The
- show a list of entities
- display entity selected
- call REST API when entity selected
- populate text area with data
- call POST API when update button clicked
- show welcome message when no entities
Let’s build a test suite which validates these assertions.
We’ll start by creating a new file in the main component folder called main.component.spec.ts. We’ll copy the basic test module configuration from the Testing Cloud Apps documentation, and then replace the instances of “TestComponent” with “MainComponent”. Then we’ll run the
eca test command to make sure everything is set up correctly. If we get a green result for the “should create” test, we’re ready for move on.
The first test we’ll add will validate that a list of entities is displayed. One of the tenets of testing is isolation- we don’t want to have any external dependencies. So we’ll need to replicate the behavior of Alma when a page with entities is displayed. For this we’ll use a mock service instead of the
CloudAppEventsService. The mock service provides a way for us to simulate navigating to a page in Alma. We’ve placed the mock and other constants into a separate file for reuse:
We need to add our mock service in the
providers property of our test module configuration. And since most of our tests rely on there being a list of entities, we add a
beforeEach method which loads the entities and calls
detectChanges to trigger change detection in the template:
Finally, we add a reference to the Angular Material test harnesses. These classes enable our tests to easily interact with the Material controls in our template. For example, in this test we get a reference to all of the material radio buttons using the
MatRadioButtonHarness class. Then we verify that the number of radio buttons matches the number of entities in our mocked page.
Next we’ll add a test which confirms that when we select an entity it is displayed in the template. Our test will use the component member
selectedEntity, first confirming it’s not defined. Then we’ll use the same test harness we used above to “check” a radio button. We then verify the
selectedEntity member is defined, and we use a test harness for material cards to confirm the entity is now displayed in the template.
However, when we first run our new test, we get an error:
Error: Timeout - Async function did not complete within 5000ms
This is because of another piece of functionality in the scaffolding. When an entity is selected, the component uses the
CloudAppRestService to retrieve the data about the selected entity. Since our test module doesn’t have any knowledge of the rest service, the request times out. Now we’ll need another strategy to intercept calls to the rest service and supply a mock response. For this we’ll use a “spy”, which spies on requests to the specified service. We define our spy in the utility module:
And then define another beforeEach function to configure the spy.
Now our test passes successfully.
In our next test, we want to ensure the rest API is called when the entity is selected. We can use the same spy we configured in the previous test. The spy supports a method called
toHaveBeenCalledWith. We use that method to confirm the rest service was called with the link of the selected entity.
We’ve now have everything in place we need to complete our last three tests:
- We confirm the text area in the template includes the results of the REST API call from the previous test
- We confirm the REST API is called when the update button is clicked, using the test harness for material buttons to “click” and using our spy to confirm the API was called with the
- We confirm the welcome message is displayed when there are no entities are shown, using the mock events service to simulate an empty entity list and checking for the existence of our
And there we have it- now we are confident that we’ve fully validated the functionality of our scaffolding, using mock services, spies, and material test harnesses to build robust and efficient tests.
Click below to view a video which walks through this blog post: