.doAction( ) – How to mock a function in AsMock that returns void
Using AsMock to mock a result being returned from a function is quite common, however, how would you mock behavior on a function which returns void ?
When unit testing a class, if we mock its dependencies, AsMock will allow us to set expectations to what will be called on the dependency. For example, a presentation model has a dependency on a service. When .makeBooking( ) is called on the presentation model (probably from a view), it will in turn call .createBooking( ) on the service.
Here is the presentation model we are testing:
Here is the service it is depending on, note how it returns a Booking object:
Here is the unit test:
Note that the nulls are just for compilation, when the test is running, your class under test will pass in run-time values.
We set an expectation that createBooking will be called, we also tell the mocking framework that when it is called, we will return a particular result, in this case a newly created booking; .returnValue(expectedBooking). That booking is also mocked, since currently the only concrete class we have is the presentation model, the remainder, including Booking are all interfaces.
Lets beef up the expectation a bit more and tell the framework what values the parameters should be; we will add some constraints:
Now lets assume that due to a refactoring, it has been decided that the createBooking( ) function in the service will no longer return a result, but instead will take a list of existing bookings as a parameter which it will ‘fill’ with the additional booking which has been created.
So the code in our class under test (PM) has to be changed to this:
We are now not in a position to be able to tell the mock to return a result as the function on the service now returns void. So how do we mock the list getting filled with the newly created booking ? This is where the .doAction() function comes into play. Instead of .returnValue( ) we can us .doAction( ) . We provide a function as a parameter to .doAction( ) within which you can write code to ‘simulate’ the behavior of you dependency (i.e. the service in our case). The function has the same parameters as the function which is being mocked, so if the function we were mocking was:
then the Expectation would look like this:
So we now need to change our unit test to use .doAction:
Of-course in reality createBooking in our service would probably be doing much more, for example calling on to integration layer classes such as remote calls, SQLite libraries, etc, but that’s the beauty of mocking.
There is nothing to say you can’t use .doAction for functions which return something other than void, you just have to make sure you return something in the anonymous function and declare its type in the function declaration.
You can check out the API docs here