115

I can write up and execute Selenium script without any special test framework but I wanted to use Junit 5 (because we have dependency with other tools) and I have never seen such error org.junit.jupiter.api.extension.ParameterResolutionException while working with Junit 4.

Currently it's Junit 5 and I googled it to get some sort of idea but can not resolve the issue.

Test script using JUnit 5, Eclipse 4.8 and Selenium:

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();
    }
}

Stack trace:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [org.openqa.selenium.WebDriver arg0] in executable [public login.loginTest(org.openqa.selenium.WebDriver)]. at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:191)

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
Mike ASP
  • 2,013
  • 2
  • 17
  • 24
  • https://stackoverflow.com/questions/51319784/junit-5-collection-type-parameters-cause-errors-with-parameterizedtest – Mike ASP Aug 15 '18 at 23:14
  • 2
    JUnit needs to instantiate the test class using its constructor which has a `WebDriver` parameter. Thus, it looks for a registered `ParameterResolver` to resolve it but there's none registered. Do you have an extension that provides the `WebDriver` instance? – Marc Philipp Aug 16 '18 at 06:22
  • 2
    no, I don't have any. How would I do that ? – Mike ASP Aug 17 '18 at 19:57

19 Answers19

241

I had both @Test and @ParameterizedTest annotating the same method. I removed the former.

Will
  • 3,770
  • 3
  • 21
  • 19
  • 3
    Having only ´@Test´ also lead me to this page. Switched it to ´@ParameterizedTest´, and it works. – jumps4fun Apr 21 '22 at 13:57
  • I had `@RepeatedTest` instead of `@Test` and also removing `@Test` solved the issue of No `ParameterResolver` registered for parameter `[org.junit.jupiter.api.RepetitionInfo arg0]`. – banan3'14 Dec 29 '22 at 15:22
36

This error appears when you try to use both @Test and @ParameterizedTest in the same test class. Removing @Test annotation will resolve the issue.

Simas Joneliunas
  • 2,890
  • 20
  • 28
  • 35
muhin
  • 533
  • 4
  • 10
24

I had the similar issue I resolved it by removing the @Test annotation and introduce annotation @ParameterizedTest

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78
Darshan
  • 409
  • 4
  • 13
22

As Marc Philipp mentioned in his comment, you need to ensure that JUnit Jupiter can instantiate your test class.

For your particular scenario, you'll need to remove your custom constructor that accepts a WebDriver.

Then you have two options:

  1. Create the WebDriver on your own -- for example, in an @BeforeAll or @BeforeEach method.
  2. Use an extension such as Selenium Jupiter to help manage the WebDriver for you.
Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
16

I also got ParameterResolutionException with JUnit 5.

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

I had written @Test methods inside the class I was testing.

This error could be fixed in two ways:

1) Either replacing import org.junit.jupiter.api.Test with import org.junit.Test, or

2) Writing tests in a separate TestClass.

Matilda Smeds
  • 1,384
  • 11
  • 18
  • In my case, 1st case only ignored the test, even though it didn't throw an error but that wasn't the desired result after all. – rpajaziti Oct 28 '22 at 00:41
14

It is maybe not an answer to the question above, but for me using Spring-Boot, and Lomboks @RequiredArgsConstructor, JUnit couldn't autowire the dependencies. My class looked like that:

@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 {}
}

Warning (experimental Lombok feature!)

Lomboks onX is experimental and comes in different flavours.

You could add onConstructor = @__(@Autowired) to the RequiredArgsConstructor annotation:

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

Without Lombok

IMHO having an IDE generated constructor with @Autowired would be better. At least for now.

@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
}
Valerij Dobler
  • 1,848
  • 15
  • 25
  • If what you are referring to `@RequiredArgsConstructor` is provided by lombok. Then what `onConstructor = @__(@Autowired)` does is add the `@Autowired` annotation to constructor parameters. If you have your own constructor, you can annotate your parameters with @Autowired manually to achieve the same behaviour. – Missaka Iddamalgoda Jan 24 '23 at 04:46
  • @MissakaIddamalgoda `@Autowired` is not added to the parameters, but to the constructor itself. Yes, you could add it to the fields, but then they cant be final any more because they will be assigned post-construct. – Valerij Dobler Jan 24 '23 at 12:39
  • Yes. What I meant is add the autowired annotation to the either Constructor or else if you only one parameter in the constructor then you annotate just the parameter itself as `MyClass(@Autowired DB db)`. I didn't suggest Autowiring the fields themselves. – Missaka Iddamalgoda Jan 25 '23 at 04:32
  • If you're not familiar with `Lombok.RequiredArgsConstructor` it generates the constructor, hence there is no constructor to add the annotation to in the source code. – Valerij Dobler Jan 26 '23 at 07:29
  • @MissakaIddamalgoda I'd suggest you read up on it, try to understand, what it is and what it is used for and then comment on it. – Valerij Dobler Jan 26 '23 at 07:32
5

I got this error because my test needed my Spring Boot server to be running first, so that dependency injection using @Autowired would get executed. I added these annotations:

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

}
Janac Meena
  • 3,203
  • 35
  • 32
5

For me, I was using

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

Instead of (quotes were wrong):

@ParameterizedTest
@CsvSource({
        "1st-param1,1st-param2",
        "2nd-param1,2nd-param2"
        })
public void isCompleted(String param1, String param2) {
slonik
  • 1,144
  • 11
  • 13
3

I had similar issue as my dependencies where using both junit4 & junit5. I made @Tests to use from junit4 i.e, import org.junit.Test. This fixed the cause.

2

Annotating test class with @ExtendWith(MockitoExtension.class) worked for me

Krzysiek
  • 21
  • 3
2

Removing constructor and adding as parameter in test method, solved my problem in 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)
    );
}
Tohid Makari
  • 1,700
  • 3
  • 15
  • 29
0

In my situation I had 2 parameters. The first parameter was using @AggregateWith, the second parameter should not have been aggregated and was already of the correct type, but JUnit tried to aggregate it as well.

Switching parameter 0 and 1 solved the issue for me (that is, the parameter annotated with @AggregateWith is now at the end).

marco
  • 711
  • 6
  • 14
0

I think the WebDriver class in your project is not Annotated as a bean and it cannot be injected, i had the same problem and when i changed the injection way from constructor injection into instance variable injection, it throws NoSuchBeanDefinitionException ("No qualifying bean of type '...service.RsRepositoryService' available: "), it does not find the bean that we are trying to inject. Hope this helps someone with this problem :)

0

I had the same error while using a wrong separator (";" instead of ",")

Zoette
  • 1,241
  • 2
  • 18
  • 49
0

If you're using Kotlin & Spring Boot, using the primary constructor to inject dependencies (as you'd normally do) would introduce this error. Solution: use property injection instead of constructor injection.

Not working:

@SpringBootTest
class Failing(val someDependency: SomeDependency) {
    @Test
    fun foo() {}
}

Working:

@SpringBootTest
class Working {
    @Autowired lateinit var someDependency: SomeDependency

    @Test
    fun foo() {}
}
Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
0

I haven't seen the answer that worked for me. I got the error because I initiated my object using a constructor instead of for each. Don't use a constructor, use beforeEach, like this:

class Testclass {
   private ObjectToRunTestsOn objectToRunTestsOn;

    @BeforeEach()
    void beforeEach() {
        objectToRunTestsOn= new ObjectToRunTestsOn();
    }
    
}
Yannick Mussche
  • 316
  • 2
  • 12
0

I have been investigated this issue in my project. I made a conclusion that this problem can occurs in 2 cases:

  1. You create a constructor with argument. The compiler cannot accept this. So you need delete argument in conctructor. Or you can make your test class abstract and delegate argument to inheritors.
  2. You create testMethod with argument. I advise to delete argument from these methods. Annotation @ParameterizedTest do not help in solving this problem for me. I use only @Test annotation
0

inject dependency as variant:

@Autowired
public WebDriver driver;
SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
0

Using JUnit 4 keywords/annotations with JUnit 5

I had "all of the above"... well, not all, but some.

I was constructing JUnit 4 test cases (@RunWith(Parameterized.class) @Test, constructor with arguments...) that would have been fine in a project with JUnit 4. In fact, their structure was copied from a similar test case for a similar class-under-test.

The problem was that, being a new project, we started with all the new stuff: left Java8 for Java11, used lambda everywhere possible, and migrate tests to JUnit 5.

The solution, then, was to write proper JUnit 5 test cases.

  • Loose @Parameters at the data generation method in favor of @MethodSource("methodName") at the test case, right after @ParameterizedTest
  • remove the constructor with parameters and put parameters in the test case instead
  • get rid of the @RunWith(Parameterized.class) at class level

By the way I still have @ParameterizedTest and @Test in the same class. The latter runs once and the former runs as many times as data the @MethodSource creates. This was not the problem.

manuelvigarcia
  • 1,696
  • 1
  • 22
  • 32