NOTE: The API Git repository got scrambled and I had to start over. The link above is correct.
In this blog post, I am switching from the Machine Learning track back to TGIMBA track. As a reminder, I will be pinging back and forth for the foreseeable future – so much cool technology, so little time.
If you remember, the most recent TGIMBA activity was to create a Continouse Integration (CI) Continouse Development (CD) Pipeline for the Typescript API and .NET Website. Since these two pipelines are now done and working, I am going to start with the upgrades I have been wanting to make for a while. I am going to start with the TypeScript API because I think its implementation will be simpler than the upgrade I want to perform on the .NET website.
For the API, there will be two main phases (interlaced with a lot of other upgrades):
- Move the SQL Server version to production.
- Modify Website to call API and retire the .NET Windows Communication Foundation (WCF) backend.
- Modify the Android App to use the API
- Move the Dynamo Db version to production.
- For this, I will need to convert the current database to its Dynamo Db equivalent.
To start, I am going to add unit tests for the current code. This will be a little bit different for me because my work to date in TypeScript has been Object Oriented (OO). When I wrote the API a while back, I just wanted to explore TypeScript because it was a new thing at work. I created functions because that was simpler. So, I am going to take advantage of this and see what type of unit testing I can do with functions. Mocking is going to be a challenge 😦
First thing is to make all functions public. This plays a bit with my OO encapsulation instincts. After that, I am going to start out with testing frameworks I have used before. This means mocha, chai and safe-mock. If there is a reason to, I will use something else. Another difference is that in work projects, we included a test directory within the source folder that contains code its tests. Here, I am going to have a separate test directory that has the same structure as source. Not sure if I will like it, but I am going to try it…so far, I like it 🙂
Soooo, I read a lot of posts on how to do Dependency Injection (DI) with Functional Programming which has been my stumbling block, How can you isolate the dependancies in a functional model like you can with an OO approach. My dependency (so far) is how to mock the SQL Server client Tedious. In my OO world, I would create a client abstraction around tedious and use a mock of the client for tests and the real client for production. Here, that is not is not an easy option. I explored having a constructor of sorts which set the dependency of the module first (which is doable), but looked painful. So, I opted to really evaluate what the purpose of testing is. Testing 101 says you test logic that is part of your application and you don’t test other libraries since that is their responsibility. Given this, I separated out the logic into pre and post methods which can be tested in isolation. The main method (one per module in this application) will then be covered with an integration test and a test sqllite3 database (a later post).
The first module I did this to was the deleteBucketListItem.ts module. I struggled a bit with the pre logic methods. The first is the parameterExists(args) method. This is already easily testable since it is isolated. How it was used by the main method was not as easily tested. So, I added evaluateParameter(args) to catch the result of parameterExists(args) and throw an error if the parameter is not good. Not crazy about the title of the second method, but it is the best I could think of. Then, I added a processResult(args) (again, not crazy about the title) that is called after the Tedious result returns. All three methods are testable without Tedious. After implementing it, it works. This may be an issue when I add the integration test(s), but so far, so good.
So, in conclusion, I used the same model with the remaining SQL Server and Dynamo Db modules and I think this is working well (at least for now). If I get further in and something starts to smell, I will adapt 🙂