I have a pretty complex test where I decided to go with approach of partial stubbing of tested class. in my test I have something like this:
val srv = new Service()
val srvSpy = spy(srv)
doReturn(now).when(srvSpy).getRunDateInTimeZone(futureChecklist)
doReturn("boo").when(srvSpy).interpolateChecklistName("name", now)
val returnTuple = (createdChlRev, createdChl)
doReturn(returnTuple).when(srvSpy).create(fChlCreatorId,
fChlCreatorEmail,
"username",
true,
templateId,
"boo",
optDueDate)(connection)
val (chlRev, chl) = srv.createFromFutureChecklist(futureChecklist)(connection)
In the code above, the first two stubbed methods working as expected. However, the last one throws an error:
[error] Tuple2 cannot be returned by create$default$8() [error]
create$default$8() should return JsObject [error] *** [error] If
you're unsure why you're getting above error read on. [error] Due
to the nature of the syntax above problem might occur because: [error]
1. This exception might occur in wrongly written multi-threaded tests. [error] Please refer to Mockito FAQ on limitations of
concurrency testing. [error] 2. A spy is stubbed using
when(spy.foo()).then() syntax. It is safer to stub spies - [error]
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
I've trying bunch of different approached of stubbing and still getting the same error. At this point I have no idea even where to look.
What am I doing wrong?
Any advice would be helpful.
Thanks
Sorry, it was my own dumb mistake. I was stubbing the spied class, but calling the original one :(
Thanks,
Related
I'm trying to write a test for the following function in Finatra HttpClient.
def executeJson[T: Manifest](
request: Request,
expectedStatus: Status = Status.Ok): Future[T] = {...}
According to another question answered on StackOverflow. mocking generic scala method in mockito. This is a shorthand for:
def executeJson[T](
request: Request,
expectedStatus: Status = Status.Ok)
(implicit T: Manifest[T]): Futuren[T] = {...}
So I tried,
verify(httpClientMock, times(1)).executeJson[JiraProject]
(argThat(new RequestMatcher(req)))(Matchers.any())
Unfortunately, it didn't solve my problem. I still got the following error.
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at org.specs.mock.MockitoStubs$class.argThat(Mockito.scala:331)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
I also tried Matchers.eq(Manifest[JiraProject]), it complains that value Manifest of type scala.reflect.ManifestFactory.type does not take type parameters.
I'm new to Scala and Mockito, is there anything I did wrong or I misunderstood?
Thanks in advance for any help!
Found out the problem! So the executeJson actually takes 3 params- request, expectedStatus, and a Manifest. However, because expectedStatus is an optional, I didn't explicit pass it, that's why it complained. So, the final code should be verify(httpClientMock, times(1)).executeJson[JiraProject](argThat(new RequestMatcher(req)), Matchers.any[Status])(Matchers.any())
Your problem is that you're using equality in the first parameter and matcher for the second one. Try using matchers for all arguments.
But a bigger problem that I feel here is that you're trying to mock 3rd party library - this is something you should avoid. This would also solve your problem. Here's some extra read about it - TDD best practices: don't mock others
Trying to run one of apache sparks example codes (https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/graphx/AggregateMessagesExample.scala) I get the following compile error
too many arguments for method sendToDst: (msg: (Int, Double))Unit
[error] Error occurred in an application involving default arguments.
[error] triplet.sendToDst(1, triplet.srcAttr)
[error] ^
[error] one error found
But looking at the mehtods it seems to be correct. Not sure what is wrong here.
It looks like the method you are calling expects a single argument (a Tuple2) and you are passing in 2 arguments.
Try
triplet.sendToDst((1, triplet.srcAttr))
I'm learning Scala (2.11) and the Play Framework, and i'm trying to implement a Many to Many relation between Person and Skill with Squeryl (0.9.5-7). Multiple Persons can share Skills, and a Person can have many Skills.
The Squeryl docs tell me to do this:
class PersonToSkill(val personId: Long, val skillId: Long) extends KeyedEntity[CompositeKey2[Long,Long]] {
def id = compositeKey(personId, skillId)
}
But the compiler tells me this:
not found: value compositeKey
[error] def id = compositeKey(personId, skillId)
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
Also, i cannot find compositeKey(fieldId, fieldId) in the docs. I have no idea where it it originates from..
I'm hoping someone can help me solve my problem, or at least explain me where to look for a solution. Thanks!
You can find compositeKey located within org.squery.dsl.QueryDsl
You'll want to make sure you import org.squeryl.PrimitiveTypeMode._ which extends QueryDsl. That should resolve the error you are receiving.
This works
(x => s"$x")
but this
(s"${_}")
results in
[error] ...: unbound placeholder parameter
[error] (s"${_}")
Is this a case of leaky abstraction?
Furthermore: (s"$_") fails with a completely different output:
[error] ...: invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected
[error] (s"$_")
[error] ^
[error] ...: unclosed string literal
[error] (s"$_")
Calling string interpolation a leaky abstraction is totally right in my opinion. While it works fine in most cases, there are many edge cases where it just doesn't work the way how one expects it. This one is another incarnation of such an edge case.
I don't know why s"$_" is not accepted by the compiler. Some time ago there were a pull request that introduced this syntax for pattern matching: PR 2823
Interestingly this PR also contains test cases that test that the underscore outside of a pattern match produces an error.
Unfortunately there is no further description why this is implemented the way it is implemented.
Som Snytt, the guy who implemented the PR is active on SO, hopefully he can tell more.
Can someone tell me what "Fragment evaluation error" means, or where I might look for solutions? I sometimes (but not always) get lots of these errors (without changing my code):
[error] ! Fragment evaluation error
[error] ThrowableException: Could not initialize class code.model.Post$ (FutureTask.java:138)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply$mcZ$sp(PostSpec.scala:68)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
Line 68 of PostSpec is the first line in the (specs2) test that references the Post model companion object:
val test4 = Post.fixJValue(toextract4).extract[Selection]
I'm using Scala 2.9.0-1.
Also: I have no idea whether it matters, but Post is a net.liftweb.mongodb.record.MongoRecord class companion object:
object Post extends Post with MongoMetaRecord[Post] { ... }
In a specs2 specification, Fragments are pieces of the specification. A Fragment can be a Text, an Example, a Step.
Some fragments, like Example and Step are meant to be executed and are supposed to catch Exceptions so that they can be marked as failures. But they won't catch Errors (except AssertionErrors). So if an Example throws an OutOfMemoryError, this will be reported as a Fragment evaluation error.
Other fragments, like Text fragments are not supposed to throw exceptions when being evaluated. If they do, you will get the same Fragment evaluation error message.
Without seeing the full specification it's hard for me to say what's happening there but I suspect that you had a non-Exception type thrown in the body of an Example. But I have more questions than answers for now:
where is test4 declared? Inside the specification body? Inside a Context case class?
since errors happen intermittently, are you sure you always have a proper mongodb context? Maybe your specification examples are being executed concurrently on the same mongo db instance?