我的应用程序中有两个服务bean,它们都实现一个接口。对于该接口,所有方法都必须执行相同的操作(内部原理不同)。
因此,我想编写一套针对两种服务运行的测试。 (不想写重复的代码)
构造测试以完成此任务的最佳方法是什么?
(我已经标记了junit4,因为这是我目前受限的版本。)
答案 0 :(得分:0)
您可以创建一个包含JavaConfig中的实现列表的bean:
public class TestConfig {
@Bean
MyService myService1(){
return new MyService1();
}
@Bean
MyService myService2(){
return new MyService2();
}
@Bean
public List<MyService> myServices(MyService myService1, MyService myService2){
List<MyService> allServices = new ArrayList<>();
allServices.add(myService1);
allServices.add(myService2);
return allServices;
}
}
并最终在测试中迭代此列表:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TestConfig.class)
public class ServicesTest {
@Autowired
private List<MyService> allServices;
@Test
public void testAllServices(){
for (MyService service : allServices) {
// Test service here
}
}
}
答案 1 :(得分:0)
少数选项:
您可以将所有类存储在类似List<Class<? extends YourInterface>> classes = Arrays.asList(Implementation.class)
的常量中,遍历这些类并为每个类调用方法
您可以使用Reflections查找实现特定接口的所有类,并为每个类循环遍历。
答案 2 :(得分:0)
您可能会自动列出您的服务列表,并按照某些建议进行遍历和测试每个实现。但出于多种原因,我想说这实际上不是一个很好的解决方案:
您可以通过类型参数获得所有花哨的信息,并从带有class BaseTest<HW extends HelloWorldInterface >
的通用基类(如@Autowired HW hw
继承,然后简单地通过class HelloGermanyTest extends BaseTest<GutenTag>
扩展此类,其中GutenTag implements HelloWorldInterface
但是我已经尝试过了,并且发现更简单地针对接口编写断言函数如下:
public static void assertImplementationSaysHelloWorld(HelloWorldInterface hello, String expectedResult) {
assertEquals(expectedResult, hello);
}
正在进行的事情少得多,并且该函数比继承具有更高的可重用性。例如,如果我有一个实现多个接口的类,则使用继承方法将迫使我编写更多的类来测试每个接口。而我可以在一个测试类中使用任意数量的断言函数。
答案 3 :(得分:0)
这里的其他答案都很好,但并不完全符合我的喜好。 我最终选择了
@RunWith(@Parameterized)
(为两个服务运行测试)@RunWith(SpringRunner.class)
容器,appcontext,webmvc和注入功能)以下是摘要:
@RunWith(Parameterized.class)
...
@Parameters(name = "Cached = {0}")
public static Boolean[] data() {
return new Boolean[] { Boolean.TRUE, Boolean.FALSE };
}
@ClassRule
public static final SpringClassRule springClassRule = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Before
public void setUp() {
// logic to choose the injected service based on the true/false param
}