Using Jasmine to write isolated unit tests

September 4, 2023

I'm a big fan of testing. It's super useful

  • in the beginning, when you've only got a vague idea of what your code should accomplish (maybe only with an idea in your head)
  • while your writing code to make sure parts are doing exactly what you want them to
  • and when coming back later (and probably doing changes), to make sure you don't have any regressions.

Sometimes I write a small piece of TypeScript or JavaScript, but I still don't want to miss the opportunity to write some tests for it. Now with a fully fledged setup (like in an Angular project) that's kind of a no-brainer, as the testing environment is already set up and you can just create another .spec.ts file which will be picked up automatically.

As it turns out, testing only small, isolated pieces of JavaScript is pretty easy too, even without a whole npm project or build chain! Let's create some simple Jasmine tests with a runnable UI.

Let's take a look at a small example I did a while ago (for calculating the price of a mobile number). There is a piece of JavaScript with the calculation logic in it, mobile-number-cost.js, and we would like to make sure it works correctly.

To do so, let's create a file spec-runner.html, where we do the following:

  1. Import the necessary Jasmine dependencies
  2. Reference the JavaScript file we'd like to test
  3. Add our tests.

Simple as that! Let's see it:

<!-- Jasmine dependencies -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.4.0/jasmine.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.4.0/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.4.0/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.4.0/boot.js"></script>

<!-- Actual code to test -->
<script src="mobile-number-cost.js"></script>

<!-- Tests -->
<script>
describe('Mobile number cost', () => {
  const controller = new PhoneNumberCtrl();

  describe('Category B', () => {
    it('should recognize 5-7 same digits at the end', () => {
      expect(controller.getCategory('0791111111')).toBe('B');
      expect(controller.subcategory).toBe('5-7 same digits at the end');
    });

    it('should recognize 3 equal 3-digit block', () => {
      expect(controller.getCategory('0791791791')).toBe('B');
      expect(controller.subcategory).toBe('3 equal 3-digit blocks');
    });
  });

  describe('Category C', () => {
    it('3 blocks of 2', () => {
      expect(controller.getCategory('0754010101')).toBe('C');
      expect(controller.subcategory).toBe('3 equal 2-digit blocks');
    });
  });
 });
</script>

The tests make sure that the a certain mobile number gets recognized as the correct prize category (I just picked some example tests here, you can find the full test suite here).

That's already it! We can open the HTML-file and Jasmine will run the tests against the provided JavaScript:

Thanks for reading and happy testing :)