Mocking is useful to control the behavior of functions and objects to control the communication with other modules and external endpoints. A mock can be created by defining return values or replacing the entire object or function with a user-defined equivalent. This feature will help you to test the Ballerina code independently from other modules and external endpoints.
Mock objects
The Test
module provides capabilities to mock an object for unit testing. This allows you to control the behaviour of
the object member functions and values of member fields via stubbing or replacing the entire object with a user-defined
equivalent. This feature will help you to test the Ballerina code independently of other modules and external endpoints.
Mocking objects can be done in two ways :
- Creating a test double (providing an equivalent object in place of the real object)
- Stubbing the member function or member variable (specifying the behaviour of the functions and values of the variables)
Create a test double
You can write a custom mock object and substitute it in place of the real object. The custom object should be made structurally equivalent to the real object via the mocking features in the test module.
Example:
Let's make changes to the example in the Test a simple function to define a
test double for the clientEndpont
object.
Note: Only the
get
function is implemented since it is the only function used in the sample. Attempting to call any other member function of theclientEndpoint
will result in a runtime error.
main_test.bal
Stub member functions and variables of an object
Instead of creating a test double, you may also choose to create a default mock object and stub the functions to return a specific value or to do nothing.
Example:
The example in Test a simple function shows how the get
function of the
client object can be stubbed to return a value. Let’s make changes to that example to get a random joke from a specific
category (e.g., food or movies).
main.bal
utils.bal
The util functions below are used to validate the categories and construct errors based on the HTTP response.
test_utils.bal
The util functions below are used to construct mock responses required for testing.
Stub to return a specific value
main_test.bal
This test stubs the behaviour of the get
function to return a specific value in 2 ways:
- Stubbing to return a specific value in general
- Stubbing to return a specific value based on the input
Stub with multiple values to return sequentially for each function call
main_test.bal
This test stubs the behaviour of the get
function to return a specified sequence of values for each get
function
invocation (i.e., the first call to the get
function will return the first argument and the second call will return
the second argument).
Stub a member variable
If a client
object has a public member variable, it can be stubbed to return a mock value for testing.
Example:
main.bal
main_test.bal
This test stubs the member variable productCode
of the ProductClient
to set a mock product code.
Stub to do nothing
If a function has an optional or no return type specified, this function can be mocked to do nothing when writing test cases.
Example:
main.bal
main_test.bal
This test stubs the behaviour of the send
function to do nothing for testing the sendNotification
function.
Mock functions
The Ballerina test framework provides the capability to mock a function. You can easily mock a function in a module that you are testing or a function of an imported module by using the mocking feature. This feature will help you to test your Ballerina code independently from other modules and functions.
The object specified with the @test:Mock{}
annotation will be considered as a mock function, which gets triggered in
place of the real function.
-
moduleName : "<moduleName>" - (optional) Name of the module in which the function to be mocked resides in. If the function is within the same module, this can be left blank or "." (no module) can be passed. If the function is in a different module but within the same package, just passing the module name will suffice. For functions in completely separate modules, the fully-qualified module name must be passed, which includes the
packageOrg
(i.e.,packageOrg/moduleName
). For native functions, the Ballerina module needs to be specified. -
functionName : "<functionName>" - Name of the function to be mocked.
Example:
main.bal
main_test.bal
This is the initialization of the mock function, which should be called in place of the intAdd
function.
After the initialization, the following options can be used to stub the behaviour of a function written in the module being tested.
Stub to return a specific value
This test stubs the behaviour of the get
function to return a specific value in 2 ways:
- Stubbing to return a specific value in general
- Stubbing to return a specific value based on the input
Stub to invoke another function in place of the real
This test stubs the behaviour of the intAdd
function to substitute it with a user-defined mock function.
This test stubs the behaviour of an imported function to substitute it with a user-defined mock function.
This test calls the original intAdd
function after it has been stubbed with a user-defined mock function.