0

I'm trying to write a test method for my Spring Boot application which creates a meeting on Zoom. I haven't done any unit test before, it's my first try.

I want to test the create method of my service in different scenarios (different meeting types). To test it, I need my MeetingService interface. When I try to Autowire it with @RequiredArgsConstructor from Lombok; I get this error message:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [tech.obss.zoom.service.MeetingService arg0] in constructor [public tech.obss.zoom.ZoomIntegrationServiceApplicationTests(tech.obss.zoom.service.MeetingService,tech.obss.zoom.config.AccountConfig)].

ZoomIntegrationServiceApplicationTests:

package tech.obss.zoom;

@SpringBootTest
@RunWith(SpringRunner.class)
@RequiredArgsConstructor
@ActiveProfiles("test")
class ZoomIntegrationServiceApplicationTests {
    private final MeetingService meetingService;
    private final AccountConfig accountConfig;

    @ParameterizedTest
    @ValueSource(ints = { 1, 2, 3, 4 })
    void createMeeting(int type) {
        User user = User.builder().email(accountConfig.getEmail()).userId(accountConfig.getUserId()).build();
        meetingService.createMeeting(...);
    }

}

I've seen a solution by using @BeforeEach annotation and creating the service by yourself. However, my MeetingService has another 5 different classes on its constructor, and those 5 of them have different dependencies. That's why it would be very difficult for me to do it this way.

MeetingServiceImpl:

@Service
@Slf4j
@RequiredArgsConstructor
public class MeetingServiceImpl implements MeetingService {
    private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(3);

    private final MeetingRepository meetingRepository;
    private final CreateMeetingRepository createMeetingRepository;
    private final WebClient zoomWebClient;
    private final MeetingMapper meetingMapper;
    private final AccountConfig accountConfig;


    @Override
    public MeetingDto createMeeting(CreateMeeting createMeeting) {
      ...
    }
}

Is there an easier way to solve this?

  • https://stackoverflow.com/questions/51867650/junit-5-no-parameterresolver-registered-for-parameter How is this autowiring related, btw? – Stultuske Oct 11 '22 at 12:32
  • 2
    It doesn’t work because in the case of junit tests, the test framework comes first, constructs an instance of your test class and only then spring comes into play. That means constructor autowiring doesn’t work for junit tests because spring is not constructing instances of your testclass, junit is. Use member variable autowiring instead – Felix Oct 11 '22 at 12:33
  • I have already tried the solutions on the link (like using @ParameterizedTest). I thought it is related to autowiring because the error is about parameters on the constructor. – Umut Emre Önder Oct 11 '22 at 12:40

1 Answers1

1

The exception you see is caused by that fact that your test class ZoomIntegrationServiceApplicationTests is instantiated by JUnit. JUnit has no knowledge about your Spring services which is why it doesn't how to resolve the parameters of the constructor of the test class (you can deduce that from the fact that the name of the exception starts with org.junit...)

The easiest way to fix this is to to remove the @RequiredArgsConstructor annotation from your test class and to instead annotate your fields with @Autowired, like so:

@Autowired
private MeetingService meetingService;
@Autowired
private AccountConfig accountConfig;

Spring also has a @TestConstructor annotation that might be used for applications that run tests with JUnit Junipter.

Alex R
  • 3,139
  • 1
  • 18
  • 28