Dependency injection without classes Scala - scala

I like to write Scala code without classes, using just functions and objects.
e.g.
object Something {
def foo() = {
SomeDependency().doIt()
...
}
}
object SomethingElse {
def baz = {
val x = Something.foo()
...
}
}
However, I run into the issue that I can't test that code, since I can't mock anything out. I'd have to refactor the code and make it take a parameter and then have to needlessly instantiate classes.
class Something(someDependency: SomeDependency) {
def foo() = {
someDependency.doIt()
...
}
}
class SomethingElse(something: Something) {
def baz = {
val s = new SomeDependency()
val x = new Something(s).foo()
...
}
}
What I sometimes do is use implicits but it gets cumbersome since you need to add it to every method.
object Something {
def foo()(implicit someDependency: SomeDependency) = {
someDependency().doIt()
...
}
}
object SomethingElse {
def baz(implicit something: Something) = {
val x = something.foo()
...
}
}
In other languages like Python/JS, you can just mock the dependency directly, instead of making your class take in dependencies. Is there any way to solve this, or is just an antipattern to write scala without classes.

Despite being able to work imperatively in Scala, Scala is designed for Functional Programming. The fact that you need to mock things means that your functions have side effects, therefore, they are not pure functions so it isn't functional programming.
There are mock frameworks in Scala but they don't allow you to overwrite the functionality of your functions like you can do with Python, for example.
You could use also high order functions to pass dependencies, something like this:
object Something {
def foo(someDependencyFunction: A => B): C = {
someDependencyFunction(...)
...
}
}
object SomethingElse {
def bar(SomethingFoo: (A => B) => C)(someDependencyFunction: A => B): D = {
SomethingFoo(someDependencyFunction)
...
}
}
But I don't really see the point of avoiding classes, maybe if you explain why you don't want to use classes someone can help better on a solution

Related

Mockito-Mock functions within scala object for unit testing

I have a few functions within a scala object. The functions internally call other functions of the same object.
object A {
def method1:Unit= {
spark=CreateSparkSession.create()
Method2(spark,dbnm)
}
def Method2(spark:Sparksession, dbnm:String):Unit= {
//some implementation
}
}
How can I write Unit testcase for Method1 without actually invoking method2.
CreateSparksession is another object with create method that returns sparksession.
You cannot mock methods in an object. And you should not mock methods in class that you are testing (if it looks like you need to, it is a definite symptom of violating the single responsibility principle).
What you can do is something like this:
trait Api1 {
def method1(
...
): Unit // NB: also, should not really return a Unit: how are you going to test this???
}
trait Api2 {
def method2(...): Unit // See above
}
class Impl2 extends Api2 {
def method2(...) = // Do stuff
}
class Impl1(val api2: Api2) extends Api1 {
def method1(...) = { ... ; api2.method2(); ... }
}
// You should not really need this, but, you can have it if you want
object A extends Impl1(new Impl2)
So, now testing this code is trivial:
describe("Impl2") {
it ("does nothing") {
new Impl2().method2("foo")
// Nothing happens
// this is what I meant: how do you know it worked?
}
}
describe("Impl1") {
it ("does nothinig") {
val a2 = mock[Api2]
doNothing when a2 method2(any)
val fixture = new Impl1(a2)
fixture.method1()
// Again, nothing happens!
verify(a2).nothing("foo")
}

Is it possible to mock a function that is defined within another function?

I have some functions that access a database, which I need to mock for testing purposes.
For ease of use, I would like to define these functions within another function, where I can leverage scope to reduce the number of arguments I have to pass.
I need to test the parent function, while mocking the nested functions.
Are there any tricks to mock functions that are nested?
As a secondary question, are there ways to mock functions when nested at arbitrary depth?
And a side note: my project is light enough I'm not even using classical mocking, just stackable traits like this blog post suggests; but for this question, any kind of mocking is fine.
Here is some very simple example code:
class Storage {
def storeData(specId: Long, data: String): Unit = {
val rawPath = "/path/to/file"
def storeFsEntry: Unit = {
// do stuff
}
def storeDbEntry: Unit = {
// do stuff we need mocked
}
if ( specId == 1 )
{
storeDbEntry
storeFsEntry
}
}
}
It's not possible, but you can define a trait and implement it inside your function (if you really want this logic been implemented inside):
class Storage {
trait Storing {
def path: String //you have to define all free members
def storeDbEntry: Unit
def storeFsEntry: Unit
}
def storeData(specId: Long, data: String, storingDefault: Option[Storing] = None): Unit = {
val myStoring = new Storing {
...implement it here
}
val storing = storingDefault getOrElse myStoring
import storing._
if ( specId == 1 ) {
storeDbEntry
storeFsEntry
}
}
}
Your mock will be something like that:
trait StorageMock extends Storage {
override def storeData(specId: Long, data: String, storingDefault: Option[Storing] = None): Unit = {
val storingOverride = new Storing { ... } //mocking functionality
super.storeData(specId, data, storingDefault orElse Some(storingOverride))
}
}
new Storage with StorageMock
You may also turn storingDefault into a member instead of function parameter.
The reason why it's not possible to do same for inner functions is that they are private and also typecheck can't be performed on them (in comparison with inner traits).

How store methods vals without recreating them every method call

I have Scala class which methods use a lot of regex. Each class method use some regex patterns.
Looking from the perspective of code modularity I should store those patterns in method:
class Bar {
def foo() {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
/*...*/
}
}
But this approach is quite inefficient. Patterns are recompiled on each method call.
I could move them directly to class:
class Bar {
val fooPatt1 = "[ab]+".r
val fooPatt2 = "[cd]+".r
/*...*/
}
but in case when I have 30 methods it looks ugly.
I ended up with some hybrid solution using val and anonymous function:
val z = {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
() => { /* ... */ }
}
but I am not sure if using val to store function have some drawbacks compared to def. Maybe there is other clean solution to store methods constants without polluting the class?
Using a val is perfectly fine. There might be a (very) small performance hit, but in most (99.9%) of the applications that's not a problem.
You could also create a class for the method
// The extends is not needed, although you might want to hide the Foo type
class Foo extends (() => ...) {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
def apply() = {
...
}
}
Then in the class:
class Bar {
val foo = new Foo
}
Another solution is using traits
trait Foo {
private lazy val patt1 = "[ab]+".r
private lazy val patt2 = "[cd]+".r
def foo() = ...
}
class Bar extends Foo with ...
Note that if you have different methods like that in a single class, it can be sign that the single responsibility principle is violated. Moving them to their own class (or trait) can be a solution for that problem as well.
I would put every method with the necessary regex in it's own Trait:
class Bar extends AMethod with BMethod
trait AMethod {
private val aPattern = """\d+""".r
def aMethod(s: String) = aPattern.findFirstIn(s)
}
trait BMethod {
private val bPattern = """\w+""".r
def bMethod(s: String) = bPattern.findFirstIn(s)
}
clean
separated
easy to test (object AMethodSpec extends Properties("AMethod") with AMethod ...)
I took into account Chris comment. Putting patterns to companion object is probably the most efficient approach but very unclean when we have more methods.
EECOLOR solution is less efficient but cleaner. Traits prevents recreating patterns on each method call. Unfortunately, scala do not use same compiled pattern accross multiple class instances:
(new X).patt1==(new X).patt1 // would be false.
I've combined those two approaches and instead traits I used objects.
object X {
object method1 {
val patt1 = "a".r
}
object method2 {
val patt1 = "a".r
}
}
class X {
def method1 = {
import X.method1._
patt1
}
def method2 = {
import X.method2._
patt1
}
}
(new X).method1 == (new X).method1 // true
(new X).method2 == (new X).method2 // true
Although this approach works, I think scala should provide some solution for that problem out of box. Patterns are the simplest example. We could have other immutable objects which initialization is much more expensive.
Extracting method internals somewhere outside is still unclear. It would be nice to do it like with lazy vals. Adding one modificator should ensure that value is instance only once across all instances and methods calls. It would be something like that:
def method1 {
static val x = new VeryExpensiveObject
}

Is there an easy way to chain java setters that are void instead of return this

I have a bunch of auto-generated java code that I will be calling in scala. Currently all of the objects were generated with void setters instead of returning this which makes it really annoying when you need to set a bunch of values (I'm not going to use the constructor by initializing everything since there's like 50 fields). For example:
val o = new Obj()
o.setA("a")
o.setB("b")
o.setC("c")
It would be really cool if I could do something like this
val o = with(new Obj()) {
_.setA("a")
_.setB("b")
_.setC("c")
}
I can't use andThen with anon functions since they require objects to be returned. Am I stuck with the current way I'm doing things or is there some magic I'm not aware of.
Sure, you can use tap (the Kestrel combinator), which you presently have to define yourself:
implicit class Tapper[A](val a: A) extends AnyVal {
def tap[B](f: A => B): A = { f(a); a }
def taps[B](fs: A => B*): A = { fs.map(_(a)); a }
}
It works like so:
scala> "salmon".taps(
| println,
| println
| )
salmon
salmon
res2: String = salmon
Note also
val myFavoriteObject = {
val x = new Obj
x.setA("a")
}
will allow you to use a short name to do all the setting while assigning to a more meaningful name for longer-term use.
You can use an implicit converter from/to a wrapper class that allows chaining.
Something like:
case class ObjWrapper(o: Obj) {
def setA(a: String) = { o.setA(a); this }
def setB(b: String) = { o.setB(b); this }
def setC(c: String) = { o.setC(c); this }
}
implicit def wrapped2Obj(ow: ObjWrapper): Obj = ow.o
ObjWrapper(myObj).setA("a").setB("b").setC("c")
Actually you don't even need the implicit converter since those method have been called on myObj.
Take a look at Scalaxy/Beans. Note however that it's using macros, so it should be considered experimental.

Is it possible to (re)bind the receiver inside a block of code?

Problem
This question is motivated by trying to find a solution for this question.
Assume that you would like to construct a hierarchical structure by using the following syntax:
root {
subA {
subB("b1.1")
subB("b1.2")
}
}
The construction DSL should be type-safe, that is, it should not be possible to nest a subB directly in root, or to nest a subA in another subA. Hence, my idea is to have a method root that returns an object defining a method subA, where the latter in turn returns an object defining subB.
What I would now like to have is that the block of code passed to root, that is,
subA {
subB("b1.1")
subB("b1.2")
}
is executed such that the invocation of subB is bound to the object created by root. Basically like this
root { r: Root =>
r.subA { sa: SubA =>
sa.subB("b1.1")
sa.subB("b1.2")
}
}
but without having to make the receivers r and sa explicit.
Question: Is rebinding receivers, especially the implicit this-receiver, inside a block of code possible in Scala - maybe using macros?
Other approaches
This article describes a similarly-looking construction DSL for XML trees. Their implementation is based on the Dynamic feature and the resulting DSL syntax looks like this:
xml html {
xml head {
xml title "Search Links"
}
}
However, this approach requires explicit receivers (here the object xml), and more severely, I don't think that it is type-safe in the sense that it would statically prevent you from nesting an html node inside a title node.
I am not sure if this is usable, but it looks very similar to the code you have written. I have add , and changed the { and } into ( and ).
trait RootElement
trait SubAElement
def root(f:(() => RootElement)*) = ???
def subA(f:(() => SubAElement)*):() => RootElement = ???
def subB(s:String):() => SubAElement = ???
root(
subA (
subB("b1.1"),
subB("b1.2")
)
)
I am not sure how you want to use it, I could try and make a more specific version based on the use case if you made that available.
Edit
Is rebinding receivers, especially the implicit this-receiver, inside a block of code possible in Scala - maybe using macros?
No, as far as I can tell, that's not possible out-of-the box. You probably will be able to do it with macro's, but I can not help you with that. My limited knowledge of macro's tells me that will be quite an adventure.
To achieve the same effect without macro's I created a small example. I have removed the laziness to make it more concise.
class Root {
def subA(subA: SubA) = {
// do something with subA
}
}
class SubA {
def subB(s: String) = {
// do something with subB
}
}
case class RootElement(value: SubA)
case class SubAElement(value: String)
def root(rootElems: (RootElement)*): Root = {
val r = new Root
rootElems foreach { sub =>
r.subA(sub.value)
}
r
}
def subA(subElems: SubAElement*): RootElement = {
val sA = new SubA
subElems foreach { sub =>
sA.subB(sub.value)
}
RootElement(sA)
}
def subB(s: String): SubAElement = SubAElement(s)
root(
subA(
subB("b1.1"),
subB("b1.2")
)
)