У меня есть проект с Cucumber для java, настроенный (фактически используя Kotlin, но это просто использование java под капотом). Он использует пружину для DI и установку, которая прекрасно работает со следующей конфигурацией:
package com.cucumberproject.projectA.hooks
import com.cucumberproject.projectA.profile.ProfileManager
import com.cucumberproject.projectA.profile.EnvironmentProfile
import org.springframework.context.annotation.Bean
class AppConfiguration {
@Bean
fun profileManager(): EnvironmentProfile {
return ProfileManager().getEnvProfile(
"clientId",
"clientSecret",
TokenUrl,
AuthorisationUrl);
}
}
package com.cucumberproject.projectA.hooks
import io.cucumber.java8.En
import org.springframework.test.context.ContextConfiguration
@ContextConfiguration(classes = [AppConfiguration::class])
class SetupSteps : En {
}
import com.cucumberproject.projectA.hooks.*
import com.cucumberproject.projectA.profile.EnvironmentProfile
import io.cucumber.java.PendingException
import io.cucumber.java.Scenario
import io.cucumber.java8.En
class FeatureSteps @Autowired constructor(private var profile: EnvironmentProfile) : En {
private lateinit var scenario: Scenario
@Before
fun initialise(scenario: Scenario) {
this.scenario = scenario
}
init {
Given("A certain state") {
// code in here that works
}
Я пытаюсь создать новый проект с той же настройкой. Он имеет доступ к одному и тому же файлу AppConfiguration, файлу EnvironmentProfile и файлу SetupSteps, поскольку они извлекаются как зависимости.
package com.cucumberproject2.projectB.stepdefs
import com.cucumberproject.hooks.AppConfiguration //original project
import com.cucumberproject.hooks.SetupSteps //original project
import com.cucumberproject.stepdefs.ProgramSetupSteps //original project
import io.cucumber.java.Before
import io.cucumber.java.PendingException
import io.cucumber.java.Scenario
import io.cucumber.java8.En
import org.springframework.beans.factory.annotation.Autowired
class OtherFeatureSteps @Autowired constructor(private var setupSteps: SetupSteps) : En {
private lateinit var scenario: Scenario
@Before
fun initialise(scenario: Scenario) {
this.scenario = scenario
}
init {
Given("Some other state") {
// code here
}
}
}
При попытке запустить тесты на огурец со старым проектом все работает нормально. Когда я пытаюсь с новым проектом, я получаю эту ошибку:
Apr 08, 2020 11:36:07 AM io.cucumber.core.runtime.Runtime run
SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException: io.cucumber.core.backend.CucumberBackendException: Error creating bean with name 'com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps.<init>()
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:110)
at io.cucumber.core.cli.Main.run(Main.java:63)
at io.cucumber.core.cli.Main.main(Main.java:27)
Caused by: io.cucumber.core.backend.CucumberBackendException: Error creating bean with name 'com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps.<init>()
at io.cucumber.spring.SpringFactory.getInstance(SpringFactory.java:213)
at io.cucumber.java8.Java8Backend.buildWorld(Java8Backend.java:62)
at io.cucumber.core.runner.Runner.buildBackendWorlds(Runner.java:165)
at io.cucumber.core.runner.Runner.runPickle(Runner.java:61)
at io.cucumber.core.runtime.Runtime.lambda$null$2(Runtime.java:102)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:258)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at io.cucumber.core.runtime.Runtime.lambda$run$3(Runtime.java:102)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.SliceOps$1$1.accept(SliceOps.java:204)
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:103)
... 2 more
У меня не было большого опыта использования Spring, и первоначальный проект был настроен кем-то другим. Кто-нибудь может увидеть, что идет не так? Я попытался добавить @ContextConfiguration(classes = [AppConfiguration::class])
в начало нового файла шагов, что привело меня немного дальше и другое сообщение об ошибке:
Apr 08, 2020 11:46:20 AM io.cucumber.core.runtime.Runtime run
SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException: io.cucumber.core.backend.CucumberBackendException: Error creating bean with name 'com.cucumberproject2.projectB.stepdefs.OtherFeatureSteps': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.cucumberproject.hooks.FeatureSteps' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:110)
at io.cucumber.core.cli.Main.run(Main.java:63)
at io.cucumber.core.cli.Main.main(Main.java:27)
Но, честно говоря, я понятия не имею, если это правильная вещь. Любая помощь с этим будет высоко ценится!