In the last couple posts, I talked about Mock Objects: what they are and how to implement them in LabVIEW. In this post, I am going to talk about how to use them in unit tests.
For reference, the video below shows how to use the Class Refactoring Toolkit and how to create and use a Mock Object. If you haven’t seen it yet, it is worth watching. It will make the following discussion easier to follow.
In the video, I show an example test, so for our discussion let’s start with that. Notice that we have a classic 4 part test. First let’s focus on setting up the Mock Object.
- When setting up the Mock Object, the order is very important. The first thing is to make sure you initialize the Mock Object. This is what creates the Helper Object (which is reference-based).
- The next step is to fork the wire. The Mock Object is reference-based, so once we create the reference in the Initialize Mock, we can fork the wire to keep a reference to the mock that we can use with the verify method. This means we don’t have to worry about retrieving the Mock Object after we exercise the SUT.
- Next after we make sure to fork the wire, then we use dependency injection to pass the Mock Object to our SUT.
Building a Desired Call Log
Arguably building the desired call log could go in the verification frame, but I tend to put it in the setup frame. I like to keep the verification frame as simple as possible. When we build a call log, we are telling the mock object what calls to expect and in what order. We are also telling the mock object for each call what we expect the parameters to be. This is what gets verified.
In the pallettes under SAS there is a Mock Object Pallette. This contains the Generate Call and Add Calls to Log methods. These are used as the building blocks to build the call log. Add Calls to Log is pretty simple. Just wire an array of calls in the order you expect them to happen.
Generate Call Log is much more interesting. There are a lot of options to explore (and we will in my next post). At it’s most basic you simply wire the name of the method. If the method has parameters, you simply create a constant for each parameter. Give it the value and datatype you expect for the parameter, and make sure the label matches the label on the connector pane of the method. Then you just bundle all those together and wire that up to the parameters cluster input.
The Verify Mock Log method is pretty straightforward. You pass in the desired call log and if it matches the actual call log, it passes. Otherwise, it fails and outputs a message telling you why it failed. Note that the verify method cleans up all refnums (since they are no longer needed) so it should be the last thing you call. Note this also simply outputs a boolean so you can use it in any unit testing framework you would like.