In JUnit you can use #ClassRule to annotate an static field.
How can I do this in Kotlin?
I tried:
object companion {
#ClassRule #JvmStatic
val managedMongoDb = ...
}
and
object companion {
#ClassRule #JvmField
val managedMongoDb = ...
}
but none of the last works because rule isn't executed.
I double checked that exactly same rule works fine without static context:
#Rule #JvmField
val managedMongoDb = ...
You are not using companion objects correctly. You are declaring an object (single instance of a class) called companion instead of creating a companion object inside of a class. And therefore the static fields are not created correctly.
class TestClass {
companion object { ... }
}
Is very different than:
class TestClass {
object companion { ... } // this is an object declaration, not a companion object
}
Although both are valid code.
Here is a correct working example of using #ClassRule, tested in Kotlin 1.0.0:
class TestWithRule {
companion object {
#ClassRule #JvmField
val resource: ExternalResource = object : ExternalResource() {
override fun before() {
println("ClassRule Before")
}
override fun after() {
println("ClassRule After")
}
}
}
#Test fun testSomething() {
println("Testing...")
}
}
This outputs:
ClassRule Before
Testing...
ClassRule After
Related
I would like to write a Scala test which checks the exact class of an object created with factory method.
class Base { }
class Derived extends Base { }
class TestSpec {
test("test instance class") {
val result = new Derived()
// I want to check that result is exactly Derived type
result should be a[Derived]
result should not be a[Base]
}
}
I'm looking for something to test if object returned from my factory method for specific parameters is always base class. So it would be something like this is C#:
public class Base { }
public class Derived : Base { }
public class Program
{
public static void Main(string[] args)
{
var baseObject = new Base();
var derivedObject = new Derived();
var baseResult = baseObject.GetType().IsSubclassOf(typeof(Base));
var derivedResult = derivedObject.GetType().IsSubclassOf(typeof(Base));
Console.WriteLine(string.Format("Base is subclass of Base: {0}\nDerived is subclass of Base: {1}", baseResult, derivedResult));
}
}
you can do this :
class A{}
class B extends A{}
val result = new B()
result.getClass.getName shouldEqual classOf[B].getName
result.getClass.getName.equals(classOf[A].getName) shouldBe false
new Derived() will always be an instance of Base as it inherits from Base, which means:
new Derived().isInstanceOf[Base]
will return true.
But the opposite is false: Base won't be an instance of Derived.
Thus, to check if it's the Base class (and not the Derived class), you can use these two combined conditions:
new Base() should not be a[Derived]
new Base() shouldBe a[Base]
and to check if it's the Derived class, the following is enough:
new Derived() shouldBe a[Derived]
I have an integration test where I start an embedded MongoDB as a companion object. I want to reuse this piece of code and I am not sure if inheritance is the way to go (if possible).
It is a Spring Boot application:
This is my test:
#RunWith(SpringRunner::class)
#SpringBootTest
class RequestRepositoryTest {
#Autowired lateinit var requestRepository: RequestRepository
companion object {
private val starter = MongodStarter.getDefaultInstance()
private var _mongod: MongodProcess? = null
private var _mongo: MongoClient? = null
#BeforeClass
#JvmStatic fun beforeTest(){
val port = 27017
val _mongodExe = starter.prepare(MongodConfigBuilder()
.version(Version.Main.DEVELOPMENT)
.net(Net("localhost", port, Network.localhostIsIPv6()))
.build())
_mongod = _mongodExe.start()
_mongo = MongoClient("localhost", port)
}
#AfterClass
#JvmStatic fun afterTest(){
_mongod?.stop()
}
}
#Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull(id)
}
}
My repository class:
#Repository
class RequestRepository #Autowired constructor(val datastore: Datastore)
{
fun store(request : Request) : String =
datastore.save(request).id.toString()
}
So my question is which is the 'correct' way to go about this in Kotlin.
Update edit: As an external object the test now looks a lot cleaner and the JUnit external resource is completely reusable across test classes:
Thanks #Lovis
#RunWith(SpringRunner::class)
#SpringBootTest
class RequestRepositoryTest {
companion object {
#ClassRule
#JvmField
val mongoServer = MongoServer
}
#Autowired lateinit var requestRepository: RequestRepository
#Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull( id )
assertTrue { ObjectId.isValid(id) }
}
}
You should be able to achieve what you want using jUnit's #ClassRule and ExternalResource. No Kotlin magic needed :-)
Define an object in a separate File:
object MongoServer : ExternalResource() {
#Throws(Throwable::class)
override fun before() {
// before class
}
override fun after() {
// after class
}
}
Then use it within each test:
companion object {
#ClassRule
#JvmField
val mongoServer = MongoServer
}
The ClassRule annotation does the trick here, the companion object is necessary to make it static and the #JvmField annotation is necessary to make the field public. Those are restrictions by jUnit's rule system.
Example:
object Test {
def test = {
doTest
}
protected def doTest = {
// do something
}
}
class MockTest extends WordSpec with Mockito{
"" in {
val t = spy(Test)
// how do i stub out doTest?
}
}
I have a Test class with a protected doTest method. How do I stub out this protected method?
I would advise to make doTest package private, so that clients of your object won't be able to call it, but you'll be able to test it from within the same package.
package com.company.my.foo
object Test {
def test = {
doTest
}
private[foo] def doTest = {
// do something
}
}
and
package com.company.my.foo
class MockTest extends WordSpec with Mockito{
"" in {
val t = spy(Test)
when(t.doTest()).thenReturn("foo")
}
}
Test is a singleton (all Scala objects are), you can subclass a class, but not an object. Hence protected is a bit meaningless here - you're saying this method should only be accessible to subclasses, but it's not possible to have any (since Test is an object).
You have a couple options depending on what is best suited to your needs. 1) you can make Test a class and then extend it, or 2) change the access level of doTest to public [which is the default in Scala if you don't specify an access modifier]
I have two classes "ClassA" and "ClassB". I want to get the class object from the ClassA * and apparently I cannot do it.
class ClassA {
ClassB.getClass() // <-- won't compile
}
class ClassB {
}
The only way would be to instantiate the specific class and call the getClass() from the newly created object. But I really don't want to create a new object for this!
class ClassA {
new ClassB().getClass() // <-- compiles, but I don't want to create a new object!
}
class ClassB {
}
In Java this is straight forward. What's the problem with Scala doing the same?
*For context, I ultimately would like to obtain the FQCN of ClassB.
classOf[ClassB] will give you the Class object of ClassB.
Here is working example:
class ClassA {
val bClass = classOf[ClassB]
}
class ClassB {
}
object Main {
def main(args: Array[String]): Unit = {
println(new ClassA().bClass/*<- here you got java.lang.Class object*/.getName())
}
}
Scala 2.11.1 compiles ClassA to:
#ScalaSignature(bytes="...")
public class ClassA {
private final Class<ClassB> bClass = ClassB.class;
public Class<ClassB> bClass() { return this.bClass; }
}
How could I convert the following into scala.
public class JedisDB {
private static final JedisPool jedisPool = new JedisPool(getJedisPoolConfig());
public static JedisPoolConfig getJedisPool() {
// ..
}
public int getTest123() {
jedisPool.getResource();
// code goes here
}
}
I have seen answers do create a class and a companion object, but can someone explain to me exactly how and why I should do this?
Should I create what I want to expose as a static variable in the companion object, and the loading of the configuration file that is used to initialize the jedisPool in the class?
Do I have the option of making jedisPool public or private in the companion object?
Also (not to effect the answer to my question but as a added benefit), I read somewhere but didn't fully understand that this makes pattern makes testing difficult, are there workarounds then?
lazy val jedisPool : JedisPool = {
val poolConfig = createPoolConfig(app)
new JedisPool(poolConfig)
}
To get a resource
val j = jedisPool.getResource()
make sure you return resource after done using it.
jedisPool.returnResource(j)
Basically it does not metter if static methods will go to companion object or any other object. A companion object differs from other objects as it has access rights to the class/trait that other objects do not. But that's not really your's example.
Your sample with companion object:
// -- helpers to be able compile
class JedisPoolConfig { }
class JedisPool(p: JedisPoolConfig) {
def getResource = 1
}
// --
// everythis that should be SINGLETON goes into object
object JedisDB {
private lazy val jedisPool = new JedisPool(getJedisPool)
def getJedisPool = new JedisPoolConfig() // or any other implementation
def otherStaticMethod = new JedisDB().anyVal // wow - got access to private val.
}
class JedisDB {
import JedisDB._
def getTest123() = jedisPool.getResource
private val anyVal = "SomeValue";
// other methods
}
// other - non companion object
object JedisDB2 {
// def otherStaticMethod = new JedisDB().anyVal // no luck - no access
}