mockk, clearAllMocks or unmockkAll - kotlin

mockk 1.9.3
In the test noticed if did static mock in previous test, the next test will be using same mock.
Thought to do a reset at #After, but not sure which one to use clearAllMocks or unmockkAll.
in https://mockk.io/
unmockkAll unmocks object, static and constructor mocks
clearAllMocks clears regular, object, static and constructor mocks
but not clear what are the difference by unmocks and clears.
e.g.
#Test
fun test_1() {
mockkStatic(TextUtils::class)
every { TextUtils.isEmpty(param } returns true
//test
doSomeThingUsingTextUtils()
// verify
... ...
}
#Test
fun test_2() {
// in this test it does not want the mocked stub behavior
}
What it should use, clear or 'unmock`?

For me, understanding the difference between Clearing and Unmocking was sufficient.
clear - deletes internal state of objects associated with mock
resulting in empty object
unmock - re-assigns transformation of
classes back to original state prior to mock
(Source)
PS: I understand the confusion! I had it as well!
Let me know if you have any questions. Thanks.

Related

How to avoid NPEs from default parameters in mocked classes?

Here's a simplified version of what I want to test with Mockito:
class UnderTest {
fun doSomething() {
foo.doAnything()
}
}
class Foo {
fun doAnything(bar: Bar = Bar())
}
class TestUnderTest {
#Mock
var underTest: UnderTest
#Test
fun testDoSomething() {
underTest.doSomething() // Causes NPE
}
}
UnderTest is being tested. Its dependencies, like foo, are mocked. However, when my tests call UnderTest.doSomething(), it crashes. doSomething() calls Foo.doAnything(), letting it fill in the null parameter with the default - and the code that runs in that default parameter initialization is outside of the control of my test, as it's inside the static, synthetic method created for the byte code.
Is there a magical Mockito solution to get around this very situation? If so, I would love to hear it. Otherwise, I believe the options I have are:
To use PowerMock or Mockk to be able to mock things Mockito can't
To change Foo to have two doAnything() methods; one would have zero parameters, would call Bar() and pass it to the other.
To change Foo.doAnything() to accept a nullable parameter, then to have the body of the function call Bar() and use it.

mockk, what is just run

Could not find explanation about the "just run", what does it mean when stub a function with it?
Will it make the mock object to call its real function, or make the function run a stub which does nothing?
Is there sample for showing some real use case?
#Test
fun `mocking functions that return Unit`() {
val SingletonObject = mockkObject<SingletonObject>()
every { SingletonObject.functionReturnNothing() } just Runs. // ???
SingletonObject.otherMemberFunction(). //which internally calls functionReturnNothing()
//...
}
with or without this every { SingletonObject.functionReturnNothing() } just Runs stub, the test is doing same.
Copy of the answer from #Raibaz:
just runs is used for methods returning Unit (i.e., not returning a value) on strict mocks.
If you create a mock that is not relaxed and invoke a method on it
that has not being stubbed with an every block, MockK will throw an exception.
To stub a method returning Unit, you can do
every { myObject.myMethod() } just runs
No, it doesn't (like mockito's .thenCallRealMethod()) :)
It "just runs", meaning it does not do anything.
To run the real method you can use:
every { ... } answers { callOriginal() }

How to mock a constructor with a spy?

I am currently trying to test my Exposed Kotlin code. I have a table that follows the form
object Foo: Table() {
*parameters*
}
and a method that looks something like
fun addNewFoo(){
Foo.insert { ... }
}
I'm testing addNewFoo and I want to verify the insert occurred, ideally using something like
verify { FooSpy.insert { ... } }
How do I mock the Foo table to be a spy so I can verify the call occurred, or what other approach should I take to verify this method being called?
You can first mock your singleton Foo class using mockkObject() and then verify. Here is the code:
mockkObject(Foo) // mock the object
addNewFoo() // call function that we're testing
verify { Foo.insert(any()) } // verify
There is discussion of ways to go about it: https://github.com/JetBrains/Exposed/issues/317
There seems to be no real intended way for testing but making small test tables in a test data base is the closest you can get.

Specifying method's behaviour via EXPECT_CALL vs in body

From what I understand gmock (and I'm new to it) EXPECT_CALL allows for specifying how a method will behave when it's called (in this case I'm mostly interested in what it will return). But I could just as well define the method explicitly with its body. Example:
class Factory
{
int createSomething();
};
class MockFactory : public Factory
{
MOCK_METHOD0(createSomething, int());
};
int main()
{
...
int something(5);
MockFactory mockFactory;
EXPECT_CALL(mockFactory, createSomething()).WillRepeatedly(Return(something));
...
}
vs
class MockFactory : public Factory
{
int createSomething()
{
return 5;
}
};
Now, if createSomething were to behave differently (return different things) in different scenarios then obviously I should use EXPECT_CALL. But if it's going to always return the same thing wouldn't it be better to just explicitly define the method's body? (Note that other methods in the mocked class might still use EXPECT_CALL.)
When you define a method you miss all the flexibility that mocking that method can give you in the tests.
If you need to assert in a test that createSomething gets called, you can only do it if you have mocked it, not if you have a standard method definition. Not in this case, but in case of methods taking parameters, it's even better to have a mock.
If you need to set up a default action that your method should perform, even when you don't set any expectations on it, do so using ON_CALL macro in the SetUp member function of a TestFixture.

JMockit basics: mocked object, mocked parameter, expectation

I just started using JMockit and I am a bit confused on some basics of JMockit, in terms of when mock object is created, mocked object scope and what is the effect of mock etc. Please help with the following questions.
My questions refer to the following code:
public class MyClassTest
{
#Mocked({"method1","method2"})
ClassA classA; //ClassA has only static method
#Mocked
ClassB classB;
#Test
public void test1()
{
new NonStrictExpectations() {{
MyClassA.method3(classB);
result = xxx;
}};
// testing code
....
// verification
...
}
#Test
public void test2(#Mocked ClassC classC)
{
...
}
}
Questions:
About #Mocked declared as a instance variable for a junit test, like #Mocked ClassB classB:
(1) For junit, the instance variable is newly created for each test (like test1(), test2()), right? Is it true that before each test runs, a new mocked instance of ClassB is created?
(2) It mocks the class. It makes all methods in ClassB mocked for all tests (test1() and test2() in this case), right?
(3) If methods are specified for mocked object, like "#Mocked({"method1","method2"}) ClassA classA;", it means only method1 and method2 can be mocked? Can other methods be added to be mocked in Expectations for a test?
About #Mocked parameter passed in to test, like "#Mocked ClassC classC" for test2:
I assume this mock should not affect other tests? Is it true that ClassC is only mocked in test2()?
Expectation:
(1) For expectation specified in a test, is its scope local to the test, meaning the mocked method is only effective in this test? For example, ClassA.method3() is only mocked in test1(), right?
(2) The recorded method in expectation only runs when the matching method is invoked from the testing code, is it? If recorded method parameter does not match, will it run the real method?
I am getting an exception in ClassA.method3() when running test1(). Somehow the real method of ClassA.method3() is executed and gave exception. I guess it is due to parameter mismatch for ClassA.method3()?
Answering your questions:
(1) Yes; (2) yes; (3) yes, and other methods cannot be mocked in this same test class.
Yes, only in the test which has the mock parameter.
(1) Right, the expectation is only valid within the scope where it's recorded. (2) No, once mocked, the real implementation of a method is never executed.
As for the exception you get, I can't tell why it happens without seeing a complete test.