Search code examples
scalaunit-testingmockingscalatesteasymock

Easymock new object and handle its function call (No PowerMock)


I have a class which needs to be unit tested. The structure is as follows:

public class classToBeTested{
    public returnType function1(){
        //creation of variable V
        return new classA(V).map();
    }
}

The class classA is as follows:

public class classA{
    //Constructor
    public returnType map(){
        //Work
    }
}

I am creating unit tests in Scala using FunSuite, GivenWhenThen and EasyMock.
My test structure is as follows:

class classToBeTested extends FunSuite with GivenWhenThen with Matchers with EasyMockSugar {
    test(""){
        Given("")
        val c = new classToBeTested()
        expecting{
        }
        When("")
        val returnedResponse = c.function1()
        Then("")
        //checking the returned object
    }
}

What do I need to write in expectation?
How can I handle the above scenario?

Note: PowerMock can't be used.

Answer: Thanks, @Henri. After a lot of searching and the answer provided by @Henri refactoring the code is the best way to handle this situation. Reason below:

The unit test cannot mock the objects that are created by the new call(without PowerMock). And hence to test the code, we need to write the unit tests according to the conditions present in the class being used(here classA) in the class to be tested(here classToBeTested). Hence while testing classToBeTested, we need to be aware of the functioning and structure of classA and create the test cases respectively.

As now the test cases are dependent on the structure of methods in classA, implying that classToBeTested and classA are tightly coupled. And hence by TDD approach, we need to refactor the code.
In the example above:
rather than using

classA object = new classA(V);

it's better to provide the object to the method(eg: Autowiring the classA object in Spring MVC).

Open to suggestions. Also if somebody could give a better explanation please do that.


Solution

  • You can't. The instantiation of what you want to mock is in the class you want to test. So without powermock, you need refactoring to make it work.

    The minimum would be to extract the class creation into another method

    public class classToBeTested{
        public returnType function1(){
            //creation of variable V
            return getClassA(V).map();
        }
    
        protected classA getClassA(VClass v) {
            return new classA(v);
    }
    

    Then, you can do a partial mock. I don't know how to do it in scala, so the code below is probably wrong but I hope you will get the idea.

    class classToBeTested extends FunSuite with GivenWhenThen with Matchers with EasyMockSugar {
        test(""){
            Given("")
            val c = partialMockBuilder(classToBeTested.class).addMockedMethod("getClassA").build()
            val a = mock(classA.class)
            expecting{
                expect(c.getClassA()).andReturn(a)
                expect(a.map()).andReturn(someReturnType)
            }
            When("")
            val returnedResponse = c.function1()
            Then("")
            //checking the returned object
            // whatever you need to check
        }
    }