I'm having trouble utilizing Powermock, Mockito, and Kotlin to mock up a return value when
the function signature that needs overriden contains varargs.
Function to mock/override:
public BoundStatement bind(Object... values);
Test File:
class DbSessionTest {
var preparedStatement: PreparedStatement? = null
#Mock
var boundStatement: BoundStatement? = null
#Before
fun setup() {
initMocks(this)
whenever(preparedStatement?.bind(any())).thenReturn(boundStatement)
// Also, have tried it like this
whenever(preparedStatement?.bind(any<Array<Any>>())).thenReturn(boundStatement)
}
}
The fuction in the actual code is called like so:
internal fun createBoundStatement(query: String, vararg params: Any): BoundStatement {
val preparedStatement = prepare(query)
val boundStatement = preparedStatement.bind(*params)
return boundStatement
}
When I step through and the varargs are dereferenced, it turns into an Object[].
When the object array contains all the same type, everything works fine, but when
it contains type String and type Integer, the mock fails to happen and null is
returned.
Note: I have also included com.nhaarman.mockito_kotlin.any package for their specific
any function and anyVararg, but that did not work either.
What is the proper way to mock this so that no matter the type in the Object array,
it will always return the mocked value?
Nicholas Hauschild's answer make me think about removing powermock and just going with regular mockito and junit separately and that worked. Removing powermock and Upgrading mockito to v2.18.3 fixed the issue.
Related
I am trying mockito to mock a getValue function that consumes a java class as parameter.
To simplify, i did the following test:
#Test
fun test1() {
val map = HashMap<String,Any>()
val v:Long = 1L
map["K"]= v
println(map["K"]!!::class.java) //prints class java.lang.Long
println(Long::class.java) //prints long
val dss = Mockito.mock(DataSnapshot::class.java)
Mockito.`when`(dss.getValue( map["K"]!!::java.class))
.thenReturn( map["K"]!!)
//production code uses calls the function like this but it fails to get the value. Returns null;
Assert.assertEquals( map["K"],dss.getValue(Long::class.java))
}
As the prints show, the type in map["K"]!!::class.java is different from Long::class.java.
If i mock the method using the type inline it works:
Mockito.`when`(dss.getValue( Long::class.java))
.thenReturn( map["K"]!!)
How can i mock the method in a way that the type parameter hasn't to be determined by a long switch logic?
Some insides in kotlin and java types could help.
If you're asserting against java.lang.Long, use Long?::class.java. Long::class.java will give you the primitive long on the JVM. Nullable Long instead maps to the boxed version - java.long.Long.
I have a sample method(which I need to write test case) as given below,
fun setName(val auxName:String) {
val configUrl = getConfig(auxName)
}
I want to mock the getConfig method and return a specific string value.
getConfig is a method in a Kotlin Object as below,
object Configuration{
fun getConfig(auxName:String){
....
}
}
Below is the test that I tried
#Test
fun setTest()
{
val testname="test"
val testObject=Mockito.mock(Configuration::class.java)
doReturn("configTest").`when`(testObject).getConfig(Mockito.anyString())
setName(testname)
}
I am not getting any error but the method getConfig is not mocked. The actual implementation is executed. I tried using Powermockito also. Please help me with this
the problem is probably with singleton object, you can try this answer: https://stackoverflow.com/a/37978020/3703819
How to mock Kotlin extension function using Mockito or PowerMock in tests? Since they are resolved statically should they be tested as static method calls or as non static?
I think MockK can help you.
It supports mocking extension functions too.
You can use it to mock object-wide extensions:
data class Obj(val value: Int)
class Ext {
fun Obj.extensionFunc() = value + 5
}
with(mockk<Ext>()) {
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
}
If you extension is a module-wide, meaning that it is declared in a file (not inside class), you should mock it in this way:
data class Obj(val value: Int)
// declared in File.kt ("pkg" package)
fun Obj.extensionFunc() = value + 5
mockkStatic("pkg.FileKt")
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
By adding mockkStatic("pkg.FileKt") line with the name of a package and file where extension is declared (pkg.File.kt in the example).
More info can be found here: web site and github
First of all, Mockito knows nothing Kotlin specific language constructs. In the end, Mockito will have a look into the byte code. Mockito is only able to understand what it finds there and what looks like a Java language construct.
Meaning: to be really sure, you might want to use javap to deassemble the compiled classfiles to identify the exact names/signatures of the methods you want to mock.
And obviously: when that method is static, you have to user PowerMock, or JMockit; if not, you should prefer to with Mockito.
From a java point of view, you simply avoid mocking static stuff; but of course, things get really interesting, now that different languages with different ideas/concepts come together.
Instance extension functions can be stubbed and verified like this with the help of mockito-kotlin:
data class Bar(thing: Int)
class Foo {
fun Bar.bla(anotherThing: Int): Int { ... }
}
val bar = Bar(thing = 1)
val foo = mock<Foo>()
with(foo) {
whenever(any<Bar>().bla(any()).doReturn(3)
}
verify(foo).apply {
bar.bla(anotherThing = 2)
}
I use mockk library.
For extension file write java name, like this:
#file:JvmName(name = "ExtensionUtils")
package myproject.extension
...
And for fast codding I created file with different extension mocks:
object FastMock {
fun extension() = mockkStatic("myproject.extension.ExtensionUtils")
fun listExtension() = mockkStatic("myproject.extension.ListExtensionUtils")
}
In test call this:
FastMock.listExtension()
every { itemList.move(from, to) } returns Unit
Imagine I have the following class.
class SomeClass {
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
// some stuff
}
}
So the shortcutMethod is a shortcut to the other method. Let us say I want to write a test that given and $arg1 the shortcutMethod will correctly call method with the correct arguments.
So far I think I figured I need to mock the class to expect a call to method with some arguments and then call shortcutMethod on the mock object like so (note I am using Mockery).
$mock = m::mock("SomeClass");
$mock = $mock->shouldReceive('method')->times(1)->withArgs([
'foo',
'something'
]);
$mock->shortcutMethod('foo');
This results in an exception like so shortcutMethod() does not exist on this mock object.
Did I misunderstand the usage for mocking? I understand it makes more sense for objects that are dependency injected into the class, but what in this scenario? How would you go about it? And perhabs more importantly, is this sort of testing useless, and if so, why?
You should use mocking to mock out the dependencies of the class under test, not the class under test itself. After all, you are trying to test the real behavior of your class.
Your example is a little basic. How you would test such a class would depend on what your method function does. If it returns a value that is in turn returned by shortCutMethod then I would say that your should just be asserting the output of shortCutMethod. Any dependencies within the method function should be mocked (methods belonging to other classes). I'm not that familiar with mockery, but I've given a tweaked version of your example a go.
class SomeClass {
private $dependency;
public function __construct($mockedObject) {
$this->dependency = $mockedObject;
}
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
return $this->dependency->mockedMethod($arg1, $arg2);
}
}
$mock = m::mock("mockedClass");
$mock->shouldReceive('mockedMethod')->times(1)->withArgs([
'foo',
'something'
])->andReturn('returnedValue');
$testCase = new SomeClass($mock);
$this->assertEquals(
'returnedValue',
$testCase->shortcutMethod('foo')
);
Having said that, it is possible to partially mock your class under test so that you can test the real behavior of the shortCutMethod function but mock out the method function to assert that it is called with the expected arguments. Have a look at partial mocks.
http://docs.mockery.io/en/latest/reference/partial_mocks.html
Here is my situation:
I want to test on the "HasSomething()" function, which is in the following class:
public class Something
{
private object _thing;
public virtual bool HasSomething()
{
if (HasSomething(_thing))
return true;
return false;
}
public virtual bool HasSomething(object thing)
{
....some algo here to check on the object...
return true;
}
}
So, i write my test to be like this:
public void HasSomethingTest1()
{
MockRepository mocks = new MockRepository();
Something target = mocks.DynamicMock(typeof(Something)) as Something;
Expect.Call(target.HasSomething(new Object())).IgnoreArguments().Return(true);
bool expected = true;
bool actual;
actual = target.HasSomething();
Assert.AreEqual(expected, actual);
}
Is my test written correctly?
Please help me as i can't even get the result as expected. the "HasSomething(object)" just can't be mock in that way. it did not return me 'true' as being set in expectation.
Thanks.
In response to OP's 'answer': Your main problem is that RhinoMocks does not mock members of classes - instead it creates mock classes and we can then set expectations and canned responses for its members (i.e. Properties and Functions). If you attempt to test a member function of a mock/stub class, you run the risk of testing the mocking framework rather than your implementation.
For the particular scenario of the logical path being dependent on the return value of a local (usually private) function, you really need an external dependency (another object) which would affect the return value that you require from that local function. For your code snippet above, I would write the test as follows:
[Test]
public void TestHasSomething()
{
// here I am assuming that _thing is being injected in via the constructor
// you could also do it via a property setter or a function
var sut = new Something(new object());
Assert.IsTrue(sut.HasSomething);
}
i.e. no mocking required.
This is one point of misunderstanding that I often had in the past with regards to mocking; we mock the behaviour of a dependency of the system under test (SUT). Something like: the SUT calls several methods of the dependency and the mocking process provides canned responses (rather than going to the database, etc) to guide the way the logic flows.
A simple example would be as follows (note that I have used RhinoMocks AAA syntax for this test. As an aside, I notice that the syntax that you are using in your code sample is using the Record-Replay paradigm, except that it isn't using Record and Replay! That would probably cause problems as well):
public class SUT
{
Dependency _depend
public SUT (Dependency depend)
{
_depend = depend;
}
...
public int MethodUnderTest()
{
if (_depend.IsReady)
return 1;
else
return -1;
}
}
...
[Test]
public void TestSUT_MethodUnderTest()
{
var dependency = MockRepository.GenerateMock<Dependency>();
dependency.Stub(d => d.IsReady).Return(true);
var sut = new SUT(dependency);
Assert.AreEqual(1, sut.MethodUnderTest());
}
And so the problem that you have is that you are attempting to test the behaviour of a mocked object. Which means that you aren't actually testing your class at all!
In a case like this, your test double should be a derived version of class Something. Then you override the method HasSomething(object) and ensure that HasSomething() calls your one.
If I understand correctly, you are actually interested in testing the method HasDynamicFlow (not depicted in your example above) without concerning yourself with the algorithm for HasSomething.
Preet is right in that you could simply subclass Something and override the behavior of HasSomething to short-circuit the algorithm, but that would require creating some additional test-dummy code which Rhino is efficient at eliminating.
Consider using a Partial Mock Stub instead of a Dynamic Mock. A stub is less strict and is ideal for working with Properties. Methods however require some extra effort.
[Test]
public void CanStubMethod()
{
Foo foo = MockRepository.GenerateStub<Foo>();
foo.Expect(f => f.HasDynamicFlow()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething(null)).IgnoreArguments().Return(true);
Assert.IsTrue(foo.HasDynamicFlow());
}
EDIT: added code example and switched Partial Mock to Stub