Test method without class initialization

I'm very new to unit testing, I'm wondering if there is a way to test a method without initializing the class. The reason I am asking is because there are many objects in the constructor, which means a lot of mocking interruption, while from careful validation methodToTest

, there seems to be no object attribute being used. This is not my code, otherwise the method might be converted to static.

class ExampleClass {
   public ExampleClass(FirstClass fc, SecondClass sc, ThirdClass tc) {}

   public void methodToTest(FourthClass foc) {}
}

      

+3


source to share


6 answers


Ok I seem to have found a way. Since the method has nothing to do with the state of the object, I could mock the object and tell MockRunner to use the real method when it is called. This is called partial mockery. The way to do it



    ExampleClass = PowerMockito.mock(ExampleClass.class);
    when(ExampleClass.methodToTest(foc)).thenCallRealMethod();

      

+1


source


You have several options:



  • Make the method static so you don't need a reference to the actual object. This will only work if the method doesn't need any state of the ExampleClass (i.e. whatever it needs is passed in the method arguments).
  • Extract this method into a different class (perhaps using the method object pattern) that is easier to test on its own. This refactoring is called replacing a method with a method object .
+1


source


Usually, having many parameters in constructors is a hint of a bad concept. You better rethink objects and classes to reduce the argument to give to the constructor.

If you don't want that, you can use some "TestUtil" for which you instantiate the class.


Example:

public class MyTestUtils {
    public createValidFirstClass() {
        return new FirstClass(/* some arguments here */);
    }
    public createValidSecondClass() {
        return new SecondClass(/* Some arguments here */);
    }
    public createValidThridClass() {
        return new ThridClass(/* Some arguments here */);
    }
    public createValidExampleClass() {
        return new ExampleClass(createValidFirstClass(), createValidSecondClass(), createValidThridClass());
    }
}

      

This class MUST be in your test suites, not your project, and should not be used outside of tests, it would be very bad practice, use Factory or Builder for your real projects.



Anyway, I think the best solution is to rethink you. Example:

public class People {
    public People(String firstName, String lastName, Date birth, Date death) {
    }
}

      

As you can see, it is a pain in the ass to control that the whole given parameter was formatted correctly and not null.

This number of arguments passed to the method can be reduced in this way.

public class People {
    public People(PeopleNames names, Period period) {
    }
}
public class PeopleNames {
    public People(String firstName, String lastName) {
    }
}
public class PeopleNames {
    public People(Date begin, Date end) {
    }
}

      

+1


source


As far as I know, you cannot conduct a test without initializing the class.

Three test stages: Arrange, Action, and Approval. The class must be initialized in the location portion to retrieve the required methods in the concrete class that you are testing.

0


source


I don't know what your method does, but if it is possible for your application, you can simply make it methodToTest

static, which will allow you to call it without an instance of the class.

Alternatively, you can avoid too many instances by creating one instance in the method @BeforeClass

that will be used for all tests, but again I don't know what you are doing to make this undesirable.

0


source


Use suppression from PowerMockito.

import org.powermock.api.support.membermodification.MemberModifier; import org.powermock.api.support.membermodification.MemberMatcher; suppress(MemberMatcher.constructor(ExampleClass.class))

0


source







All Articles