Learning Objectives: Week of May 25, 2020

Unit Testing With NUnit

There are three stages that happen when unit testing. Create a test that fails, make this test pass, and then refactor the code you have written. When working on an individual test it is important to remember to arrange, act, and then assert. This might look like setting up objects or mock data, doing something with those objects, and then asserting the return value from a function. With unit testing, you are breaking apart the requirements of your project into smaller pieces so that your code becomes more modularized.

I am viewing unit testing as a skill that can be used even when not testing your application. My recommendation is to focus on one feature or task at a time, write the code for that task, and then test the design. So often we lose our train of thought because we are switching between the logic and the representation of this logic. Add time to compile and we waste more time being distracted.


Jest is a testing framework created by Facebook, the same company that developed React. Out of the box with a “create-react-app” instance, Jest is available without having to install any dependencies. If you need to only test individual files be sure to install the global package through either Yarn or NPM.

The only problem I had was trying to get the toThrow() matcher to work with a function that clearly would throw a new error. I have not tested to see if this works with the Jest CLI outside of a new React application.

Github Actions

Today there are over 3,800 prescripted actions to choose from. You can now set up continuous integration with actions such as when a pull request is submitted or when a brach is pushed. If you can think of an automated action, you can probably find an action for it.

I recently build two continuous integration actions, one for deploying my app to Heroku and another for running my tests. All actions you create are executed with criteria. A criterion could trigger an action when a branch is pushed or when a pull request has been created. In my case, whenever I merge my changes from my develop branch into master my app will be deployed to Heroku. My other action will run any Jest tests when I push to develop.


If you need to cache data that is greater than 5 – 10MB, indexedDB will run in your browser and is a great alternative method from localStorage. In my case, I needed to use IndexedDB for caching images for my Pokemon Go Pokedex companion app. The problem was when updating a pokemon, the image associated with the monster would load an image from an absolute URL. If the request for the image fails, the image for the Pokemon does not load. Instead, I wrote a script which will go through all of the Pokemon in my database, fetches an image, gets the images buffer byte array, converts the array into a base64 string, and then saves the string and type to my cloud Mongo database in a unique collection. The time to load an image was taken just as long when fetching from a database as it was from fetching from a URL.

This is where IndexedDB comes in handy because I needed a way to cache an image on subsequent visits. With IndexedDB I learned that the structure of saving data is different than rows saved in SQL. IndexedDB is a key value-based storage system which is similar to Redis. Below is a synopsis of what it takes to use IndexedDB, however you can also use the getting started guide.

  1. With IndexedDB you have to check for browser compatibility
  2. Open a new instance of a database and assign to a variable such as “request”
  3. Check if the “request” was successful and assign a variable to the result of the request
  4. Use the onupgradedneeded function to set up the structure of your database
  5. To read or write, open a new transaction with the type readwrite or readonly
    1. Set up a new object store and attach an action method: add({}), delete(id), etc
    2. Check that the object store transaction was successful or not using a callback method: onsuccess()or onerror()

Leave a Reply

Your email address will not be published. Required fields are marked *