Specs2 version 4 - how to use Future matchers (such as `awaitFor`) - specs2

Upon upgrading to specs2 version 4, our tests which were using Future matchers started to fail.
This is what those tests look like:
class SomeSpec(implicit ee: ExecutionEnv) extends Specification {
"some spec" should {
"check some async thing" in {
val asyncThing = ... // calls test subject
asyncThing must beEqualTo("some value").awaitFor(10.seconds)
}
}
}
I can see mentions of breaking changes to future matchers in this blog post:
http://etorreborre.blogspot.com.au/2017/08/specs2-4x.html
But it's not clear to me what I need to change to make the tests pass (or whether there is a solution at all)
The user guides on specs2 website don't seem to have been updated either.

The answer is: don't change anything but your specs2 version where the fix is :-). This issue is fixed in specs2 4.0.1.

Related

Mocking DynamoDB in Spark with Mockito

I want to mock Utilities function dynamoDBStatusWrite so that when my spark program will run, it will not hit the DynamoDB.
Below is my mocking and test case stuff
class FileConversion1Test extends FlatSpec with MockitoSugar with Matchers with ArgumentMatchersSugar with SparkSessionTestWrapper {
"File Conversion" should "convert the file to" in {
val utility = mock[Utilities1]
val client1 = mock[AmazonDynamoDB]
val dynamoDB1 =mock[DynamoDB]
val dynamoDBFunc = mock[Utilities1].dynamoDBStatusWrite("test","test","test","test")
val objUtilities1 = new Utilities1
FieldSetter.setField(objUtilities1,objUtilities1.getClass.getDeclaredField("client"),client1)
FieldSetter.setField(objUtilities1,objUtilities1.getClass.getDeclaredField("dynamoDB"),dynamoDB1)
FieldSetter.setField(objUtilities1,objUtilities1.getClass.getField("dynamoDBStatusWrite"),dynamoDBFunc)
when(utility.dynamoDBStatusWrite("test","test","test","test")).thenReturn("pass")
assert(FileConversion1.fileConversionFunc(spark,"src/test/inputfiles/userdata1.csv","parquet","src/test/output","exec1234567","service123")==="passed")
}
}
My spark program should not try to connect dynamoDB. but is trying to connect
You have 2 problems there, for starters the fact that you mock something doesn't replace it automatically in your system, you need to build your software so components are injected and so in the test you would be providing a mock version of them. ie, fileConversionFunc should receive another parameter with the connector to Dynamo.
That said, it's considered a bad practice to mock library/3rd party classes, what you should do there is to create your own component that encapsulates the interaction with Dynamo, and then mock your component, as it's an API you control.
You can find a detailed explanation of why here

Why is scalatest MockitoSugar deprecated?

I'm new to writing junit tests in Scala and I'm using Mockito to mock objects. I'm also using scalatest_2.12-3.0.4. The ScalaTest documentation (like here) shows the syntax to create the mock using MockitoSugar, i.e.
val mockCollaborator = mock[Collaborator]
Eclipse shows org.scalatest.mock.MockitoSugar crossed out in the import statement, indicating it is deprecated. The only alternative I've found is, don't use MockitoSugar and instead do:
val mockCollaborator = mock(classOf[Collaborator])
This seems to work fine too, so I'm curious what ScalaTest is recommending me to use.
Or for that matter, why else would I use MockitoSugar? Does it have any other features? I've been unable to find any documentation about it, except that everybody seems to use the shorthand mock[] notation.
Base on the issue and some comments, the answer should be changed:
the MockitoSugar has been moved to a separate project: https://github.com/scalatest/scalatestplus-mockito
need to add a new dependency to use it
https://mvnrepository.com/artifact/org.scalatestplus/mockito-3-4_2.13/3.3.0.0-SNAP3
testCompile group: 'org.scalatestplus', name: 'mockito-3-4_2.13', version: '3.3.0.0-SNAP3'
origin issue: https://github.com/scalatest/scalatest/issues/1789
As reported in the source you should use org.scalatest.mockito.MockitoSugar instead of org.scalatest.mock.MockitoSugar

Why use Specs2 over JUnit? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
We went through online material such as scalatest site. What are advantages of using scala testing framework Specs2? How does it add to the project over JUnit?
I'm a little reluctant to answer this because it's a quite subjective thing.
But I could summarise it as "In the same way Scala gives you new and cleaner ways to solve problems over Java, Specs2 gives you new and cleaner ways to test over JUnit".
Some quick examples:
Mockito is a first-class citizen
Mockito is my favourite JVM mocking library; using it with Specs2 is as simple as mixing in a trait and you get a nice DSL for verification:
class MySpec extends Specification with Mockito {
// Setup:
val mockConnection = mock[Connection]
...
// Verification: (in a test)
there was one(mockConnection).get("www.google.com")
}
ScalaCheck is a first-class citizen
ScalaCheck can save a heap of time "fuzzing" inputs to your functions, and again, a simple trait mixin gets you all of its power within your Specs2 tests.
Run a test in a Scope
Ever had a problem where tests would work on your machine but break elsewhere, because your machine ran them in a certain order? Or got into "mocking hell" due to interactions between stubbed collaborator behaviour? Specs2 lets you put the entire test into a Scope to contain all of that state and stop it from leaking into other tests:
class AnotherSpec extends Specification with Mockito {
class FooScope extends Scope {
val mockResponse = mock[Response]
val mockConnection = mock[Connection]
...
mockConnection.execute returns mockResponse
def frobulate(s:String) = {
// Use mockResponse, mockConnection, etc ...
}
}
"My thing" should {
"Do stuff" in new FooScope {
frobulate("hello")
there was one(mockConnection).post(...)
}
}
Scopes help you DRY up your tests as well as stop state leaks between them.
Plus
"Blocks" to group related tests ("My thing" should)
Readable, space-separated test names ("throw an exception if argument < 0" in)
Readable DSL for matching (result must have length(7))
Matchers for Scala-idiomatic types (result must beNone)
Easily temporarily disable a test with pending
Generate HTML reports/output with a DSL
Downsides
In an attempt to make this answer slightly more objective, I should also point out this article by the esteemed Bill Venners about compile time which points out that a Specs2 mutable.Specification, due to large numbers of implicits and function declarations, is almost an order-of-magnitude slower to compile than a roughly-equivalent JUnit test. It also does not scale well over large numbers of tests. Or at least it didn't when the article was written in early 2013. There are now approaches you can use to address this.

Concise yet scalable Scala/sbt testing to verify Project Euler answers

I’m using Project Euler to learn functional programming in Scala, along with sbt and other best practices. My initial stab at creating tests to verify solutions using ScalaTest was:
package euler
import org.scalatest._
class SolutionsSpec extends Spec with Matchers {
"The problems" should "have the correct solutions" in {
Problem1.solve should be ( 233168 )
Problem2.solve should be ( 4613732 )
Problem3.solve should be ( 6857 )
Problem4.solve should be ( 906609 )
}
}
This is concise, but I’m afraid it might not scale if I ever get to harder problems with longer run times. As far as I can tell, I can't test individual problems this way.
I have searched on GitHub and found two helpful examples, similar to what I am trying to do:
danielmiladinov/ProjectEuler-Scala
todd-cook/Effective-Scala-with-Project-Euler
Both are more verbose than I would like, since I’m basically just testing a mapping from problem number to solutions.
My question: Is there a concise and elegant way to do this testing that is still flexible so that I can check the result for a single or group of problems?
Edit: I found this answer discouraging TDD with Project Euler. To clarify, I am writing unit tests for math helper functions as well. My purpose for checking the answers is partly to check for regressions, but most important as an exercise.
Edit 2: I am now trying to use FunSuite:
class SolutionsSuite extends FunSuite with Matchers {
test("Problem 1") { Problem1.solve should be ( 233168 ) }
test("Problem 2") { Problem2.solve should be ( 4613732 ) }
test("Problem 3") { Problem3.solve should be ( 6857 ) }
test("Problem 4") { Problem4.solve should be ( 906609 ) }
}
This might be closer to what I want. The output looks better:
$ sbt test
...
[info] SolutionsSuite:
[info] - Problem 1 (28 milliseconds)
[info] - Problem 2 (4 milliseconds)
[info] - Problem 3 (38 milliseconds)
[info] - Problem 4 (172 milliseconds)
But I have still not been able to figure out how to run a subset of the problems. This question seems to indicate that what I am looking for is not yet possible with sbt: Run just a specific scalatest test from sbt.
Edit 3: It looks like the ability to run single test function as opposed to an entire suite is targeted for sbt 0.13.3 per issue Allow running of single junit test #911.
Edit 4: For reference, my Project Euler GitHub project.
You might like to copy my setup at https://github.com/sethtisue/project-euler . Each test looks like:
class Problem1 extends Problem(1, "12345") {
def solve: Int = ...
}
Where the "12345" is the expected answer (always a string), and the return type of solve can be anything (since it's just going to get .toStringed, since a string is what you're going to end up entering at the Euler site).
Problem is defined such that each problem is its own suite, so you can easily use sbt's test-only command to run just the problems you want.

eclipse does not treat a scalatest flatspec as junit test

here is my test case , while i right click the file eclipse doest not show any run as junit test option. I try to manual create run configuration but does not take any sense.
scala version:2.8.1 scalatest:1.3 eclipse:3.6.2
package org.jilen.cache.segment
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
#RunWith(classOf[JUnitRunner])
class RandomSegmentSpec extends FlatSpec with ShouldMatchers {
val option = SegmentOptions()
"A Simple Segment" should "contains (douglas,lea) after put into" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment("douglas") should be("lea")
}
it should "return null after (douglas,lea) is remove" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment -= ("douglas")
segment("douglas") should equal(null)
}
it should "contains nothing after clear" in {
val segment = RandomSegment.newSegment(option)
segment.put("jilen", "zhang")
segment.put(10, "ten")
segment += ("douglas" -> "lea")
segment += ("20" -> 20)
segment.clear()
segment.isEmpty should be(true)
}
}
I've encountered this seemingly randomly, and I think I've finally figured out why.
Unfortunately the plugin doesn't yet change package declarations when you move files, nor the class names when you rename files. (Given you can put multiple classes in one file, the latter will likely never be done.) If you are used to the renamings being done automagically in Eclipse, like I am, you're bound to get caught on this.
So... check carefully the following:
the package declaration in your Scala file matches the Eclipse package name
the name of the test class in the Scala file matches the name of the Scala file
I just ran into this, fixed both, and now my test runs!
This is a known problem with the Eclipse IDE for Scala. I'm currently working on the plugin for this. Watch this space.
I found Scalatest to be very bad at integrating with Eclipse (running the tests from eclipse showed that it ran them - but they would not pass or fail, but simply show up as passive blank boxes).
For some reason I could NOT get it to work after 3 hours of trying things!
Finally I tried specs2 - and it worked (Scala 2.9, Junit4 and Eclipse 3.6)!
They have a great doc here:
http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Runners+guide
Since I don't care which testing framework to use, I will try Specs2 purely from the convenience point of view.