FlexTradeUKLtd/jfixture

sameInstance customizations are not validated

Opened this issue · 1 comments

The following typo leads to false positive tests. Meaning the set-up completes successfully and this may never be discovered depending on accesses to the list. Here's a test case that should be added to JFixture's test suite:

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;

    @Test
    public void test() {
        abstract class X {}
        class Y extends X {}
        class Fixt { @Fixture List<X> list; }
        JFixture fixture = new JFixture();
        fixture.customise().sameInstance(X.class, Y.class); // typo, should be useSubType

        Fixt fixt = new Fixt();
        FixtureAnnotations.initFixtures(fixt, fixture);

        assertThat(fixt.list, notNullValue());
        assertThat(fixt.list, hasSize(3));
        assertThat(fixt.list.get(0), instanceOf(Y.class));
        assertThat(fixt.list.get(1), instanceOf(Y.class));
        assertThat(fixt.list.get(2), instanceOf(Y.class));
    }

Asking for a List<X> I get a List<Class>. Since JFixture found X.class in the registry, it could very simply check that the sameInstance that we passed in is indeed an instance of X (or null) and not something else. This validation could be even done at the time sameInstance is called.

Note: sameInstance has generic protection (<T> and Class<T>), but it's not applied here:
sameInstance(X.class, Y.class) calls the (Type, T) overload.

Disclaimer: I know you're not maintaining this repo, just wanted to record this bug/enhancement.

Here's an IntelliJ IDEA structural search inspection to find instances
(in inspectionProfiles/Project_Default.xml):

    <inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
      <replaceConfiguration name="JFixture: Invalid usage of sameInstance, use useSubType instead" text="$o$.sameInstance($x$, $y$)" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="false" shortenFQN="false" replacement="$o$.useSubType($x$, $y$)">
        <constraint name="o" nameOfExprType="com.flextrade.jfixture.FluentCustomisation" exprTypeWithinHierarchy="true" formalTypeWithinHierarchy="true" within="" contains="" />
        <constraint name="x" nameOfFormalType="java.lang.Class" negateName="true" negateFormalType="true" wholeWordsOnly="true" within="" contains="" />
        <constraint name="y" nameOfExprType="java.lang.Class" within="" contains="" />
      </replaceConfiguration>