Testing Legacy AngularJS Code
The classic Karma/Jasmine testing setup used by AngularJS-era applications.
What you'll learn
- Recognize Jasmine's describe/it/expect testing structure in existing AngularJS test files
- Explain what AngularJS's $httpBackend mock is used for in tests
- Describe why an existing test suite is valuable context before modifying legacy behavior
Explanation
AngularJS-era applications were typically tested with Karma (a test runner that launches real browsers to execute tests) and Jasmine (the testing framework providing describe/it/expect). A typical test file structure: describe("MainController", () => { it("sets a default greeting", () => { /* ... */ expect(scope.greeting).toBe("Hello!"); }); }); -- describe groups related tests, each it is one test case, and expect(...).toBe(...) (or similar matchers) makes the actual assertion.
AngularJS's built-in testing utilities include $httpBackend, a mock for $http/$resource calls in tests -- it lets a test declare an expected request ($httpBackend.expectGET("/api/users").respond(200, [...])) without making a real network call, then verify the expected requests actually happened ($httpBackend.flush()/$httpBackend.verifyNoOutstandingRequest()).
Before modifying legacy AngularJS behavior, checking whether an existing test file already covers the code you're about to touch is genuinely valuable: passing tests give you a safety net for confirming your change didn't break existing behavior, and a test's describe/it names alone can clarify what a piece of legacy code was originally intended to do, which isn't always obvious from the implementation alone.
Guided lab
Predict: A Jasmine-style test's pass/fail result
This models Jasmine's describe/it/expect structure with plain functions, since a real test runner can't execute here. Predict which test passes and which fails.
function greet(name) {
return `Hello, ${name}!`;
}
function it(description, testFn) {
try {
testFn();
console.log(`PASS: ${description}`);
} catch (e) {
console.log(`FAIL: ${description} -- ${e.message}`);
}
}
function expect(actual) {
return {
toBe(expected) {
if (actual !== expected) {
throw new Error(`expected ${expected} but got ${actual}`);
}
},
};
}
it("greets with the given name", () => {
expect(greet("Ada")).toBe("Hello, Ada!");
});
it("greets with a different name (deliberately wrong expectation)", () => {
expect(greet("Grace")).toBe("Hi, Grace!");
});Stuck? Get a hint.
Common mistakes
- Skipping a check for existing tests before modifying legacy behavior, missing a ready-made safety net for the change.
- Confusing $httpBackend (a testing mock) with $http (the real service used in application code) -- they're related but serve different purposes.
- Assuming Jasmine's describe/it structure is unique to AngularJS -- it's a general JavaScript testing framework, also used well beyond AngularJS specifically.
Knowledge check
Takeaway
Check for existing Jasmine tests (and $httpBackend-mocked HTTP expectations) before modifying legacy behavior -- they're a safety net and a source of intent.
Summary
AngularJS-era apps typically use Karma+Jasmine (describe/it/expect) for tests, with $httpBackend mocking HTTP calls; existing tests are valuable context before making changes.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.