Junit 5 - No ParameterResolver registered for parameter

216.9k Views Asked by At

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)

20

There are 20 best solutions below

0
Sam Brannen On BEST ANSWER

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.
1
Matilda Smeds On

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.

2
Will On

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

0
muhin On

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

0
Janac Meena On

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 () {
...

}
0
Krzysiek On

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

1
slonik On

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) {
0
marco On

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).

0
Darshan On

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

1
Ravindra VL On

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.

0
Lisen Saka On

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 :)

5
Valerij Dobler On

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
}
0
Tohid Makari On

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)
    );
}
0
Zoette On

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

0
Stefan van den Akker On

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() {}
}
0
Yannick Mussche On

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

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
segadev On

inject dependency as variant:

@Autowired
public WebDriver driver;
0
manuelvigarcia On

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.

0
Ogwuche Chris On

You need to use @Autowired

for example:
@Autowired public AuthServiceImpl authServiceImpl;