Search code examples
javajunitguice

Using non-static injected services in JUnit Parameterized Tests


I want to use Guice and GuiceBerry to inject a non-static legacy service into a factory class. I then want to inject that factory into my Parameterized JUnit test.

However, the issue is JUnit requires that the @Parameters method be static.

Example factory:

@Singleton
public class Ratings {
    @Inject
    private RatingService ratingService;

    public Rating classicRating() {
         return ratingService.getRatingById(1002)
    }

    // More rating factory methods
}

Example test usage:

@RunWith(Parameterized.class)
public class StaticInjectParamsTest {
    @Rule
    public GuiceBerryRule guiceBerryRule = new GuiceBerryRule(ExtendedTestMod.class)

    @Inject
    private static Ratings ratings;

    @Parameter
    public Rating rating;

    @Parameters
    public static Collection<Rating[]> ratingsParameters() {
    return Arrays.asList(new Rating[][]{
            {ratings.classicRating()}
            // All the other ratings
        });
    }

    @Test
    public void shouldWork() {
        //Use the rating in a test

    }
}

I've tried requesting static injection for the factory method but the Parameters method gets called before the GuiceBerry @Rule. I've also considered using just the rating's Id as the parameters but I want to find a reusable solution. Maybe my approach is flawed?


Solution

  • My solution was to add a RatingId class that wraps an integer and create a factory RatingIds that I could then return static and use as parameters. I overloaded the getRatingById method in my RatingService interface to accept the new RatingId type, and then inject the rating service into my test and use it directly.

    Added factory:

    public class RatingIds {
        public static RatingId classic() {
            return new RatingId(1002);
        }
        // Many more
    }
    

    Test:

    @RunWith(Parameterized.class)
    public class StaticInjectParamsTest {
        @Rule
        public GuiceBerryRule guiceBerryRule = new GuiceBerryRule(ExtendedTestMod.class)
    
        @Inject
        private RatingService ratingService
    
        @Parameter
        public RatingId ratingId;
    
        @Parameters
        public static Collection<RatingId[]> ratingsParameters() {
        return Arrays.asList(new RatingId[][]{
            {RatingIds.classic()}
            // All the other ratings
            });
        }
    
        @Test
        public void shouldWork() {
            Rating rating = ratingService.getRatingById(ratingId.getValue())
            //Use the rating in a test
    
        }
    }