Scala steps should use dependency injection, like Java
mpkorstanje opened this issue · 3 comments
From cucumber/cucumber-jvm#1075
Summary
I have found that the Scala step classes are required to have a no-args constructor, but I'd like to be able to have my glue classes depend on one another like the Java glue can.
From the Java docs:
we strongly recommend you include one of the Dependency Injection modules as well. This allows you to share state between Step Definitions without resorting to static variables (a common source of flickering scenarios).
val dslClasses = packages flatMap { classFinder.getDescendants(classOf[ScalaDsl], _) } filter { cls => try { cls.getDeclaredConstructor() true } catch { case e : Throwable => false } }This
filterwill silently ignore any Step classes which do not have a no-args constructor.See also #755 for another difference between Scala and Java here.
Expected Behavior
- I'd expect to be able to add a Glue class as a constructor param to a Step class, and have the DI framework create and inject an instance, like the Java API allows:
class MySteps(connector: MyConnector) { Given("""^some setup$"""){ () => connector.something() } }
- Also, I think that the
filterabove ought to print a warning when a Glue class that inherits fromScalaDslis rejected for having the wrong constructor, as it took me a while to figure out what was going on here.Current Behavior
- Any
ScalaDslclasses with constructors like that shown above are not loaded into the backend- No warning is currently given.
Possible Solution
I should think that most of the
JavaBackend.loadGluecode could be used directly by the ScalaBackend, instead of its own less fully-featured version (some allowances are currently made in the ScalaBackend for "MODULE$" fields, but I don't immediately see why that's necessary).Steps to Reproduce (for bugs)
Hopefully the above is clear enough; please let me know if not.
Context & Motivation
I'm starting a new Scala proejct and I'd like to use
cucumber-jvm. I have experience usingcucumber-jvmon Java projects and Scala experience.Your Environment
n/a
Just reading this and I think there is no need for this feature in Scala.
Scala usually does not need dependency injection in the same way Java does. You can just use Traits do create your steps and then bring it all together in a test class that extends all these Traits.
That sounds like a reasonable work around for now but it be nice if the trait aggregating class wasn't needed.
some allowances are currently made in the ScalaBackend for "MODULE$" fields, but I don't immediately see why that's necessary
The MODULE$ field comes with Scala object which are by definition singletons.
I believe that is the reason why there is a special case in the code for this.
But... if we want a cleaner approach, we should not allow steps to be defined in object I guess.