0

I want to use mockito for mocking the constructor call when a specific argument is passed.

Lets say this is my class -

public class MyTestClass {
    private final String argument;

    public MyTestClass(String argument) {
        this.argument = argument;
    }
}

now suppose there is a test which calls MyTestClass object = new MyTestClass("abcd");

now I want to mock the constructor call using mockedConstruction such that when "abcd" is passed as argument then return mockObject.

I tried this way -

public void setUp() throws Exception {
        try (MockedConstruction<MyTestClass> mockConstruction = Mockito.mockConstruction(MyTestClass.class, (mock, context) ->{
                        if(context.arguments().get(0).equals("abcd")){
                            mock = mockObject;
                        } )  
        {
            
        }
    }

But this is not working as expected. Please help me correct my code, I am beginner.

3
  • 1
    mock = mockObject; - that's definitelly not going to work, read Is Java "pass-by-reference" or "pass-by-value"? Instead configure the mock - when(mock.someMethodCall()).thenReturn(something).
    – Chaosfire
    Commented May 31 at 6:55
  • @Chaosfire thanks, so there is not alternative of Powermock.whenNew().withArguments().thenReturn(someMockedObject) using mockedConstruction? Instead I have to configue the mock
    – Arjun
    Commented May 31 at 7:10
  • You can refer different solutions as mentioned in post: stackoverflow.com/questions/13364406/… Commented Jun 5 at 6:52

2 Answers 2

0

There is a good library that offers a solution to the trouble of creating Mock objects.

We recommend using naver/fixture-monkey.

You can do the scenario you want as follows. (The example you showed has a final field, so to use the solution I suggest, you need to add @ConstructorProperties to the constructor. (See https://naver.github.io/fixture-monkey/v1-0-0-kor/docs/generating-objects/introspector/ ))

import java.beans.ConstructorProperties;

public class MyTestClass {

    private final String argument;

    @ConstructorProperties("argument")
    public MyTestClass(String argument) {
        this.argument = argument;
    }
}


import com.navercorp.fixturemonkey.api.introspector.ConstructorPropertiesArbitraryIntrospector;
import com.navercorp.fixturemonkey.FixtureMonkey;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;


class MyTestClassTest {


    @Test
    void test() {
        FixtureMonkey fm = FixtureMonkey.builder()
        .objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
        .build();

        MyTestClass sample = fm.giveMeBuilder(MyTestClass.class)
            .set("argument", "abcd")
            .sample(); // argument field of sample instance is "abcd"
    }

}

-1

since you want to mock a constructor, the best option is to use it like this:

public class MyTestClassTests {

  @Test
  public void your_test() {
    // given
    MyTestClass myTestClassMocked = mock(MyTestClass.class);

    // when

    // then
  }
}

Or if you want to input an already defined value (constant) into the mocked constructor you could do this:

public class MyTestClassTests {

  @Test
  public void your_test() {
    // given
    MyTestClass myTestClassMock = Mockito.spy(new MyTestClass("argument"));

    // when

    // then
  }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.