Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test class should have exactly one public zero-argument constructor

I have written a test class, such that is following

public class MyParameterizedClassTest extends BaseRepositoryTest {
    private int multiplierA;
    private int multiplierB;
    public MyParameterizedClassTest(int multiplierA) {
        this.multiplierA = multiplierA;

    }   

    @Parameters
    public static Collection<Object[]> data() { 
        Object[][] data = new Object[][] { { 1 }, { 5 }, { 121 } };
        return Arrays.asList(data);
    }

    @Test
    public void testMultiplyException() {
        assertEquals("Result", multiplierA * multiplierA,multiply(multiplierA));
    }

    public int multiply(int a){
        return a*a;
    }
 }

And My BaseRepositoryTest class is following

@RunWith (Parameterized.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public abstract class BaseRepositoryTest extends
    AbstractJUnit4SpringContextTests {



    @Inject
    SessionFactory sessionFactory;

    private Transaction transaction;

    public Session getSession() {
        Session session;
        try {
            session = sessionFactory.getCurrentSession();
        } catch (SessionException se) {
            session = sessionFactory.openSession();
        }
        return session;
    }

    @Before
    public void setUp() throws Exception {
        transaction = getSession().beginTransaction();
    }

    @After
    public void tearDown() throws Exception {
        if (transaction != null) {
            transaction.rollback();
        }
        getSession().close();
    }

    @Before
    public void baseSetUp() {
        MockitoAnnotations.initMocks(this);
    }
}

When I run my test class it shows like,

 Test class should have exactly one public zero-argument constructor:at 
 org.junit.runners.BlockJUnit4ClassRunner.validateZeroArgConstructor

I want to make a test method with @parameters,so please Can anyone please help to find the solution

like image 801
Md Aslam Avatar asked Oct 31 '14 10:10

Md Aslam


2 Answers

JUnit 4 vs 5 (Jupiter)

I had this issue when I imported the wrong Test class. While a constructor was using JUnit 5 features, I imported the old org.junit.Test rather than org.junit.jupiter.api.Test.

like image 175
s1m0nw1 Avatar answered Nov 13 '22 03:11

s1m0nw1


I think the problem is that you defined two test runners. One by yourself @RunWith (Parameterized. class) and one that comes with spring, because an AbstractJUnit4SpringContextTests defines a @RunWith(SpringJUnit4ClassRunner.class).

Since Junit can only deal with one @RunWith you can only use @Parameterized or AbstractJUnit4SpringContextTests. If you want to use both you have to use @Parameterized and than do the same logic that a SpringJUnit4ClassRunner does on your own.

A simple approach can be to just use spring's org.springframework.test.context.TestContextManager.

@RunWith(Parameterized.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public abstract class BaseRepositoryTest extends AbstractJUnit4SpringContextTests {

    private TestContextManager testContextManager;

    @Before
    public void setUpContext() throws Exception {
        this.testContextManager = new TestContextManager(getClass());
        this.testContextManager.prepareTestInstance(this);
    }

}

But this only ensures that the TestExecutionListeners are invoked. Spring normally does a lot more like application context caching and so on. Also a tear down method should be implemented that closes the application context.

like image 10
René Link Avatar answered Nov 13 '22 04:11

René Link