Junit 5 - 没有为参数注册解析器

119

我可以编写并执行Selenium脚本,而不需要任何特殊的测试框架,但是由于我们与其他工具存在依赖关系,我希望使用Junit 5。然而,在使用Junit 4时,我从未遇到过像org.junit.jupiter.api.extension.ParameterResolutionException这样的错误。

目前我正在使用Junit 5,并通过谷歌搜索获取一些思路,但无法解决问题。

测试脚本使用Junit 5Eclipse 4.8Selenium

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public  class loginTest  {
    public  WebDriver driver = null;

    public loginTest(WebDriver driver) {
        this.driver=driver;
    }

    @BeforeEach
    public void setUp() throws Exception {
        driver.get("google.com");
        System.out.println("Page title is: " + driver.getTitle());
    }

    @Test
    public void test() {
        // some action here I have in original script
        System.out.println("Page title is: " + driver.getTitle());
    }

    @AfterEach
    public void tearDown() throws Exception {
        driver.quit();
    }
}

堆栈跟踪:

org.junit.jupiter.api.extension.ParameterResolutionException: 在可执行文件 [public login.loginTest(org.openqa.selenium.WebDriver)] 中未注册参数解析器,该参数为 [org.openqa.selenium.WebDriver arg0]。 at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:191)


https://stackoverflow.com/questions/51319784/junit-5-collection-type-parameters-cause-errors-with-parameterizedtest - Mike ASP
2
JUnit需要使用带有WebDriver参数的构造函数来实例化测试类。因此,它会寻找已注册的ParameterResolver来解析它,但是没有注册任何一个。您是否有提供WebDriver实例的扩展? - Marc Philipp
2
没有,我没有任何东西。我该怎么做? - Mike ASP
19个回答

254

我曾经在同一个方法上用了@Test@ParameterizedTest两个注解。现在我已将@Test注解移除。


3
只有 @Test 也导致我进入了这个页面。将其切换为 @ParameterizedTest,就可以正常工作了。 - jumps4fun
我使用了@RepeatedTest而不是@Test,并且删除@Test解决了没有为参数[org.junit.jupiter.api.RepetitionInfo arg0]注册ParameterResolver的问题。 - banan3'14

37

当您尝试在同一测试类中同时使用@Test@ParameterizedTest时,会出现此错误。移除@Test注解将解决此问题。


28

我遇到了类似的问题,我通过移除@Test注解并引入@ParameterizedTest注解来解决它。


23

正如Marc Philipp在他的评论中所提到的,您需要确保JUnit Jupiter可以实例化您的测试类。

对于您特定的情况,您需要删除接受WebDriver的自定义构造函数。

然后,您有两个选择:

  1. 自己创建WebDriver - 例如,在@BeforeAll@BeforeEach方法中。
  2. 使用扩展(例如Selenium Jupiter)来帮助管理WebDriver

16

我在使用JUnit 5时也遇到了ParameterResolutionException

org.junit.jupiter.api.extension.ParameterResolutionException: 
No ParameterResolver registered for parameter [int[] arg0] in constructor (public my_package.MyClass(int[]))

我在被测试的类中编写了 @Test 方法。

这个错误有两种解决方法:

1)用 import org.junit.Test 替换 import org.junit.jupiter.api.Test,或者

2)在一个单独的 TestClass 中编写测试。


在我的情况下,第一种情况只是忽略了测试,即使它没有抛出错误,但这毕竟不是期望的结果。 - rpajaziti

14
也许这不是对上面问题的答案,但对我来说,使用Spring-Boot和Lombok的@RequiredArgsConstructor时,JUnit无法自动装配依赖项。我的类看起来像这样:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { TestPersistenceConfiguration.class, MyRepositoryTest.TestConfiguration.class })
@RequiredArgsConstructor
class MyRepositoryTest {
    private final MyRepository repository;
    private final TransactionTemplate tt;

// test methods...

    @Configuration
    @EnableJpaRepositories(basePackageClasses = { MyRepository.class })
    static class TestConfiguration {}
}

警告(实验性的Lombok功能!)

Lombok的onX实验性的,且有不同的风格。

您可以在RequiredArgsConstructor注解上添加onConstructor = @__(@Autowired)

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { TestPersistenceConfiguration.class, MyRepositoryTest.TestConfiguration.class })
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
class MyRepositoryTest {
// everything as before
}

没有使用Lombok

在我看来,使用@ Autowired生成的IDE构造函数可能更好。至少现在是这样。

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { TestPersistenceConfiguration.class, MyRepositoryTest.TestConfiguration.class })
class MyRepositoryTest {
    private final MyRepository repository;
    private final TransactionTemplate tt;

    @Autowired
    MyRepositoryTest(MyRepository repository, TransactionTemplate tt) {
        this.tt = tt;
        this.repository = repository;
    }
// everything else as before
}

如果你所提到的 @RequiredArgsConstructor 是由 lombok 提供的,那么 onConstructor = @__(@Autowired) 的作用是将 @Autowired 注解添加到构造函数参数中。如果你有自己的构造函数,你可以手动使用 @Autowired 注解来实现相同的行为。 - Missaka Iddamalgoda
@Autowired 不是添加到参数中,而是添加到构造函数本身。是的,您可以将其添加到字段中,但是它们不能再是 final 的,因为它们将在构造后被分配。 - Valerij Dobler
是的。我的意思是将@Autowired注释添加到构造函数或者,如果您只有一个参数,则仅将参数本身注释为MyClass(@Autowired DB db)。我没有建议自动装配字段本身。 - Missaka Iddamalgoda
如果您不熟悉Lombok.RequiredArgsConstructor,它会生成构造函数,因此在源代码中没有要添加注释的构造函数。 - Valerij Dobler
@MissakaIddamalgoda 我建议您先阅读相关资料,了解它的定义和用途,然后再发表评论。 - Valerij Dobler

5

对于我而言,我一直在使用

@ParameterizedTest
@CsvSource({
        "1st-param1","1st-param2",
        "2nd-param1","2nd-param2"
        })
public void isCompleted(String param1, String param2) {

改为(引号用错了):

@ParameterizedTest
@CsvSource({
        "1st-param1,1st-param2",
        "2nd-param1,2nd-param2"
        })
public void isCompleted(String param1, String param2) {

我在CsvFileSource中文件名写错了... - Maicon Mauricio

5

我之所以遇到这个错误是因为我的测试需要先启动Spring Boot服务器,这样使用@Autowired进行依赖注入才能被执行。我添加了以下注释:

@Transactional
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Server.class)
public MyTestClass () {
...

}

3

我曾遇到类似问题,我的依赖同时使用了junit4和junit5。我让@Tests使用了junit4,即import org.junit.Test。这解决了问题的原因。


我正在使用 import org.junit.jupiter.api.Test;你的答案有所帮助。 - theAccidentalDeveloper

2

在测试方法中移除构造函数并添加作为参数,解决了我的问题,在 JUnit 5 中。

@ParameterizedTest
@MethodSource("data")
public void check(String input, boolean expected) {
    assertThat(inpu).isEqualTo(expected);
}

private static Stream<Arguments> data() {
    return Stream.of(
            Arguments.of("A", false),
            Arguments.of("B", false)
    );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接