I'm pretty new to Scala and came from Java and got confused by some piece of code when reading this documentation. Here is the code.
val route =
path("hello") {
get {
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
}
}
Where path("hello") is the method of trait:
trait PathDirectives /*extends omitted*/ {
def path[L](pm: PathMatcher[L]): Directive[L] = pathPrefix(pm ~ PathEnd)
// the rest omitted
}
So, when we invoke the path("hello") method we would need an object implementing the trait to invoke it on. But in the example it was just a method invocation. Just like a static method.
What did I miss?
So, when we invoke the path("hello") method we would need an object implementing the trait to invoke it on.
Yes, and that object is akka.http.scaladsl.server.Directives. The reason that you don't need to write Directives.path is that the code imports Directives._, so you can call Directives' methods directly (similar to a static import in Java except the method doesn't have to be static).
Related
I'm trying to test an Object.method which contains some nested methods from a Trait apart of some calculations. These nested methods have to be mocked (they access to a DB so I want to mock their responses).
When I call the real Object.method, it should skip the nested methods call and retrieve what I want. I've tried mocking them but test is still calling them.
Here's my example source code:
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyObject extends MyTrait {
def myParentMethod(a:String) = {
val b = myMethodToMock(a)
val c = a + b
c
}
}
Then in my test:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(a)).thenReturn(b)
//Then I call the parent method:
assert(MyObject.myParentMethod(a) equals c)
It throws a NullPointerException as it's still accessing to myMethodToMock
Your code does not compile, so I am going to guess some things of what you are actually trying to do here ...
You are stubbing a method on a mock, and then calling it on a completely unrelated instance. No wonder it does not work.
A good rule of thumb (and the best practice) is to never mock classes you are actually testing. Split everything you want to mock and test separately into a separate class. This is also known as single responsibility principle (each component should be responsible for a single thing).
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyTrait extends MyTrait {
def myMethodtoMock(a: String) = ???
}
class MyObject(helper: MyTrait = MyTrait) {
def myParentMethod(a: String) = a + helper.myMethodToMock(a)
}
object MyObject extends MyObject()
Now, you can write your test like this:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(any)).thenReturn("b")
new MyObject(myTraitMock).myParentMethod("a") shouldBe "ab"
verify(myTraitMock).myMethodToMock("a")
The main difference here is that you are passing your mock into the object's constructor, so that when it calls the method, it will be the one you stubbed, not the implementation provided by the default class.
You should use composition rather than inheritance, so you can inject an instance of MyTrait that can be a mock or the real one
I have an abstract class that looks like that:
abstract class ReadOnlyJsonFormat[T] extends RootJsonFormat[T] {
final def write(obj: T): JsValue = throw DeserializationException("Unsupported operation")
}
The idea it simple: my subclasses implement a read-only JSON, I don't care about writing any object to JSON.
Now I'd like to use Mockito to test such class through a mock, where I can call the implemented method, and the following works:
"My nice test" should "raise an exception" in {
val readOnlyJsonFormat = mock[ReadOnlyJsonFormat[Int]]
intercept[DeserializationException] {when(readOnlyJsonFormat.write(1)).thenCallRealMethod()}
val exc = intercept[DeserializationException] {
readOnlyJsonFormat.write(1)
}
exc.getMessage must be ("Unsupported operation")
}
But since my method throws an exception when .write(), I'm forced to intercept such exception when defining the behavior of the mock, something that in Java was not necessary. Am I using Mockito in the wrong way? I tried using ScalaMock but I haven't found a way to call the real method on .
I'm new to unit testing in Scala and I can't find a way to stub a function defined in a singleton object.
For example:
class Profile {
def getLatest
...
Feed.getLatestEntries
...
}
object Feed {
def getLatestEntries: Future[List[FeedEntry]] { /* Access some API*/ }
}
I'm trying to unit test the getLatest function defined in the Profile class.
Since I don't want to actually access an external API through the web in my unit tests I'm trying to stub the Feed object and its getLatestEntries function to return some predefined value.
I've looked into the ScalaMock, EasyMock and Mockito frameworks but could not find a way to stub a method of a singleton object. ScalaMock states
How come all the mocking frameworks do not offer this functionality? How can I do this? stub Feed.getLatestEntries ?
Thanks
My approach has been to create the logic of the singleton as a trait and then have the object extend the trait. This allows me provide the Singleton as a default or implicit argument, but provide a stubbed out implementation for testing
trait FeedLogic {
def getLatestEntries: Future[List[FeedEntry]] { /* Access some API*/ }
}
object Feed extends FeedLogic
def somethingWantingFeed(...)(feed: FeeLogic = Feed) = { ??? }
I have the following bit of code below and need to test the email is sent when a user is suspended.
def suspendClient(client: Client, event: Event): EventResult = {
Logger.debug(String.format(s"Found Client[${client.getName}]"));
subService.suspend(client)
Mailer.sendEmailClientSuspended(client)
WebHookEventDAO.completeEvent(event.getId)
EventResult.ok
}
The main bit of logic i'm trying to test is Mailer.sendEmailClientSuspended(client) is invoked with the correct args e.g the correct Client is passed. Is it worth splitting it up into a seperate function and how difficult is it to test a 'Object' in Scala since Mailer is an Object.
Assuming you're writing your tests in Scala with MockitoSugar and ScalaTest you want to be using an ArgumentCaptor from the Mockito library. This allows you to capture the value of the client object passed as the parameter to the fundtion sendEmailClientSuspended(client).
See this stackoverflow post for a worked example you can follow. You'll need to specify the package your Client class is in, so something like this...
val capturedClient = ArgumentCaptor.forClass(classOf[com.acme.app.Client])
If your Mailer object doesn't extent a Trait currently, add one so you can mock the Trait and call verify() on it.
If you don't own the code to Mailer, you can move the call out into it's own helper class that you write, and you can then mock the new Trait. Something like this...
trait MailerTrait {
def sendEmailClientSuspended(client: Client): Unit
}
object MyMailer extends MailerTrait () {
def sendEmailClientSuspended(client: Client): Unit = {
Mailer.sendEmailClientSuspended(client)
}
}
I am trying to understand Anonymous subclass in Scala. I have written the below code:
package com.sudipta.practice.chapter8
class Person(val name: String) {
def printMyName = println("Name: " + name)
}
class AnonymousSubclass(val name: String) {
val anonymousSubclass = new Person(name){
def sayHello = "Hello, " + name
def sayBye = "Bye, " + name
override def printMyName = println("My name is: " + name)
}
}
object testPerson extends App {
def printAnonDetails (myObject: AnonymousSubclass) = {
myObject.anonymousSubclass.printMyName
}
val personObject = new Person("Sudipta")
personObject.printMyName
val anonObject = new AnonymousSubclass("Sudipta")
printAnonDetails(anonObject)
}
But what I am not able to understand what are the usages/advantages of Anonymous Subclass in Scala. If you have any points, please share here. Thanks.
Regadrs,
Sudipta
The use of anonymous subclasses in Scala is no different than the use of anonymous subclasses in Java. The most common use in Java is probably in the observer pattern as shown in the first link.
The example directly translates to Scala:
button.addActionListener(new ActionListener() {
def actionPerformed(e: ActionEvent) {
// do something.
}
});
However, in Scala you would probably rather use an anonymous function for that (if the library allows you to):
button.addActionListener(e => /* do something */)
In Scala you might use anonymous subclasses in this case, if:
Your client requires you to extend a given interface
You register for multiple events at a time (for example a java.awt.MouseListener)
These are of course only examples. In any location where not naming a class makes sense to you, you may use an anonymous (sub)class.
Anonymous classes in Scala, Java, and pretty much any other language that supports them are useful in cases where you need to pass an instance of some interface or base class as an argument to a function, and you will never need to use the same implementation anywhere else in your code.
Note that only members and methods that are defined by the interface or base class that your anonymous class implements/extends will be visible outside the anonymous class. In your example, this means that your sayHello and sayBye methods can only be called by anonymous's overrided printMyName (if this method need to call them), or the anonymous class's constructor, since nobody else outside the anonymous class will be able to know about them, as they are Not declared in the base class (Person).