Search code examples
javaunit-testinggenericsreflectioncode-coverage

Generic assertion failing


I have a simple generic, static method in Java that is failing for a class which has a private constructor. Here's the method:

public static <E> void assertThatCtorIsPrivate(Class<E> clazz, Class<?>... parameters) throws NoSuchMethodException, InstantiationException, IllegalAccessException {
    Preconditions.checkNotNull(clazz);
    final Constructor<?> constructor = clazz.getConstructor(parameters);
    constructor.setAccessible(true);
    try {
        constructor.newInstance((Object[]) null);
    } catch(InvocationTargetException e) {
        if(e.getCause() instanceof UnsupportedOperationException) {
            throw new UnsupportedOperationException();
        }
    } finally {
        constructor.setAccessible(false);
    }

    assert Modifier.isPrivate(constructor.getModifiers());
}

Here is the class I'm trying to test:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import com.google.common.base.Preconditions;
import com.google.gson.Gson;

public final class DecodeJson {

    private static final Gson GSON = new Gson();

    private DecodeJson() {
        throw new UnsupportedOperationException();
    }

    public static <E> E parse(final File file, Class<E> clazz) throws IOException {
        Preconditions.checkNotNull(file);
        Preconditions.checkArgument(file.exists() && file.canRead());
        return GSON.fromJson(new FileReader(file), clazz);
    }

    public static <E> E parse(final String content, Class<E> clazz) throws IOException {
        Preconditions.checkNotNull(content);
        Preconditions.checkArgument(content.length() != 0);
        return GSON.fromJson(content, clazz);
    }

}

In my unit test I simply have:

@Test(expected = UnsupportedOperationException.class)
public void testPrivateCtor() throws NoSuchMethodException, InstantiationException, IllegalAccessException {
    ReflectionHelper.assertThatCtorIsPrivate(DecodeJson.class);
}

I'm getting a NoSuchMethodException when I call final Constructor<?> constructor = clazz.getConstructor(parameters);. I've tried substituting ? for E and still no dice. Any insight?


Solution

  • Doing Class.getConstructor(Class<?>... parameterTypes) will only return accessible constructors.

    A private constructor is surely not accessible from outside.

    To get non-accessible constructors, use Class.getDeclaredConstructor(Class<?>... parameterTypes).