gpt4 book ai didi

java - 在 JUnit 参数化测试中使用非静态注入(inject)服务

转载 作者:搜寻专家 更新时间:2023-11-01 03:20:55 25 4
gpt4 key购买 nike

我想使用 Guice 和 GuiceBerry 将非静态遗留服务注入(inject)工厂类。然后我想将该工厂注入(inject)到我的参数化 JUnit 测试中。

但是,问题是 JUnit 要求 @Parameters 方法是静态的。

示例工厂:

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

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

// More rating factory methods
}

示例测试用法:

@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

}
}

我已经尝试为工厂方法请求静态注入(inject),但是 Parameters 方法在 GuiceBerry @Rule 之前被调用。我也考虑过只使用评级的 Id 作为参数,但我想找到一个可重用的解决方案。也许我的方法有缺陷?

最佳答案

不幸的是,JUnit 需要能够在运行任何测试之前枚举所有测试,因此必须在规则之前调用参数方法。

您可以为评分类型定义一个枚举:

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

@Inject
private Ratings ratings;

@Parameter
public RatingType ratingType;

@Parameters
public static Collection<RatingType> types() {
return Arrays.asList(RatingType.values());
}

@Test
public void shouldWork() {
Rating rating = ratings.get(ratingType);
// Use the rating in a test
}
}

编辑:枚举代码:

public enum RatingType {
CLASSIC(1002),
COMPLEX(1020);

private final int ratingId;

private RatingType(int ratingId) {
this.ratingId = ratingId;
}

// option 1: keep rating ID private by having a method like this
public get(RatingService ratingService) {
return ratingService.getRatingById(ratingId);
}

// option 2: have a package-scope accessor
int getRatingId() {
return ratingId;
}
}

编辑:如果您选择选项 2,您将添加一个新方法以从 RatingType 获取 Rating,该方法将委托(delegate)给传递 ratingId 的服务:

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

public Rating getRating(RatingType ratingType) {
return ratingService.getRatingById(
ratingType.getRatingId());
}

// More rating factory methods
}

如果您不希望 RatingType 出现在您的公共(public) API 中,您可以在您的测试中定义它,并在名为 getRating() 的枚举中使用一个方法

public enum RatingType {
CLASSIC {
@Override public Rating getRating(Ratings ratings) {
return ratings.getClassicRating();
}
},
COMPLEX {
@Override public Rating getRating(Ratings ratings) {
return ratings.getComplexRating();
}
};

public abstract Rating getRating(Ratings ratings);
}

您还可以创建值类型而不是枚举。

这假设您可以编写应通过所有 Rating 实例的测试。

如果您有一些通用测试但一些特定于评分的测试,我会制作一个包含通用测试的抽象基类,以及一个抽象createRating( ) 方法,并将其子类化为每种评级类型。

关于java - 在 JUnit 参数化测试中使用非静态注入(inject)服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30895711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com