#Unable to write test case for class Operation

1 messages Ā· Page 1 of 1 (latest)

unkempt loom
#

I have on Operation class where i have one intAdd function which just take two parameter and it return sum of it .

public class Operation {
public function intAdd(int a, intb) returns int {
return a+b
}
}
I am unable to write test case for it, not able to mock Operation class .

can anyone help me with sample test case for above class , stuck for long time or any reference

rotund barn
#

Hi @unkempt loom

You can use object mocking to write tests for this. Following is a sample demonstrating this.

main.bal

import ballerina/io;

public class Operation {
    public function intAdd(int a, int b) returns int {
        return a+b;
    }
}

Operation op = check new Operation();


public function getAdd() returns int {
    io:println(op.intAdd(3, 4));
    return op.intAdd(3, 4); // returns 7
}

main_test.bal

import ballerina/test;
import ballerina/io;

public class MockOperation {
    public function intAdd(int a, int b) returns int {
        return 5;
    }
}

@test:Config
public function testIntAdd() {
    op = test:mock(Operation, new MockOperation());
    int result = getAdd(); // returns 5
    io:print(result);

    // verify that the function returns the mock value after replacing the name
    test:assertEquals(result, 5);
}

In the above sample, when we run the testIntAdd test, it will use the MockOperation class in place of the actual Operation class and the getAdd method will call the intAdd function in the MockOperation class instead of the actual intAdd method.

You can refer the below documentations for further insight on this.
[1] https://ballerina.io/learn/test-ballerina-code/mocking/
[2] https://ballerina.io/learn/by-example/testerina-mocking-objects/

Hope this helps with your problem

Learn how to use the mocking API of Ballerina test framework to test modules independent from other modules, and external endpoints.

BBE on how to mock objects for unit testing.

unkempt loom
#

It worked thanks šŸ™‚ @rotund barn

#

It worked , my concern if operation class having N functions then same N functions we have to mock under MockOPerations right

#

there is no other way right

rotund barn
#

If there are way too many functions in your class to mock, you can also try to stub the methods.

@test:Config
public function testIntAdd() {
    op = test:mock(Operation);
    test:prepare(op).when("intAdd").thenReturn(10);
    int result = getAdd();
    io:print(result);

    test:assertEquals(result, 10);
}

Here, we would not be needing the mock class MockOperation or any of the mock methods. We will instruct the test to return a pre-determined value when the intAdd method is called.
Other than returning a value, you could stub a function to perform other tasks. You can read more on that from the below docs.
https://ballerina.io/learn/test-ballerina-code/mocking/#stub-methods
https://central.ballerina.io/ballerina/test/latest#FunctionStub

You can also stub a function to invoke another function in place of the real one

import ballerina/test;

@test:Mock {functionName: "intAdd"}
test:MockFunction intAddMockFn = new ();

@test:Config
function testCall() {
    // Stub to call another function when `intAdd` is called.
    test:when(intAddMockFn).call("mockIntAdd");
   
    test:assertEquals(addValues(11, 6), 5, msg = "function mocking failed");
}
    
// The mock function to be used in place of the `intAdd` function
public function mockIntAdd(int a, int b) returns int {
    return (a - b);
}

You can read more on that from below:
https://ballerina.io/learn/test-ballerina-code/mocking/#stub-to-invoke-another-function-in-place-of-the-real

test(v2201.10.2) - This module facilitates writing tests for Ballerina code in a simple manner. It provides a number of capabilities such as configuring the setup and cleanup steps at different levels, ordering and grouping of tests, providing value-sets to tests, and independence from external functions and endpoints via mocking capabilities.

Learn how to use the mocking API of Ballerina test framework to test modules independent from other modules, and external endpoints.

clever seal
#

Adding to @rotund barn 's response, if you are replacing your class with a mock class, you only need to mock the behavior of the functions that are being called in your test flow.

unkempt loom
#

Hey @clever seal
Having one more concern , we one class which handle very complex logic , if we stub method then how can we handle all sceanrio

#

the above approach which you mentioned was helpful if we have some databaseService class where we are connecting with database , so instead of hitting the db we can mock the response.

But how about we have fileHandler type of class which handle different type of complex logic of processing the file .
DO we still need to stub or mock line by line , it will be sometng creating replica of orginal file

#

How can we handle such type of class to write the test case

unkempt loom
#

having some private functions too

clever seal
#

@unkempt loom Since the mock is done at runtime, you should be able to set the variable to the actual class(within the test function) when you don't need to mock it.
Will that address the requirement?

unkempt loom
#

Can we schdedule call with you @clever seal

unkempt loom
#

Kindly suggest timings when you will be available ?