MockK verify return value - kotlin

I need to verify that a function is being called. When I run debug, I can see it being called but I get this error from mockk:
Verification failed: call 1 of 1: Object(#2).f(any(), any())) was not called.
My verify statemen is as follows:
verify(exactly = 1) { object.f(any(), any()) }
And I create the spy object as follows:
object = spyk(object)
The signature of the function f is:
f(any(), any()) : String
Can someone please point me in the right direction, how do I use verify for the function f. I suspect that because the function f returns a string, verify cannot match it's signature.
In any case, please let me know if you have an idea of why verify doesn't work in this case.
Thanks

Related

What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library?

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

Mockk verify fails when checking called and wasNot called

I am trying to verify that a function was not called using the following:
verify {
managementService.deleteUser(any()) wasNot Called
}
That verification fails with the message:
Verification failed: call 1 of 1:
ManagementService(#11).deleteUser(any())) was not called.
If I invert the verification to this:
verify {
managementService.deleteUser(any())
}
I still receive the same failure message.
There are other functions on ManagementService that pass wasNot Called just fine.
Why would my verification failing for wasNot Called, while the error message says the failure is because it was not called? And why would inverting the check produce the same error?
wasNot Called is not used to verify that a specific function call has not been made, but that an entire mock was never called, like this:
verify {
managementService wasNot Called
}
If you want to verify that deleteUser was not called with any argument, you can verify that the call happened exactly zero times:
verify(exactly = 0) {
managementService.deleteUser(any())
}

Mockk matching and overloaded function withArg

Hello I am trying to find a way to match an overloaded function inside of the verify using withArg
The doc doesnt really point this out
every { getResponse.Ids } returns listOf(121212L)
assert( client.getExtIds(Ids) )
verify {
client.getExtIdsCall().call(
withArg {
assertEquals(GetExtIdsRequest.builder()
.withIds("foo")
.withType("bar")
.build().hashCode(), it.hashCode()
)
}
)
}
Something like above. But unfortunately I cant because the client.getExtIdsCall().call() accepts two different types of objects. One of which has the hashCode I want. So the it can not be referred correctly to call the hashCode function
You can resolve this by explicitly specifying the type parameter of function withArg, e.g. if you want your parameter to be a Long, you can write:
withArg<Long> { ... }

Declare val without initialization in function

class Solution {
val message: String //error : val must be initialized or abstract
message = "love" //error : val cannot be reassigned
}
I understand what's happening in here - val cannot be reassigned.
So when I need val but can not initialize it i used to use by lazy
class Solution {
fun love(){
val message : String
message = "love" //this works
message = "hate" //this is error "val cannot be reassigned"
}
}
Here I can delcare val without initialization and later write codemessage = "love".what's happening here?
#deHaar noticed correctly that only var (mutable variable) is appropriate in your case.
The error you get is absolutely correct and expected.
what's happening here?
When you declare a read-only variable without initializing it you have to make sure that each execution path will have a value in this read-only variable. It means that Kotlin makes sure if your read-only variable was or was not initialized in every place it is used and raises errors if the variable is used inappropriately.
Here you have only one execution path as there are no when or if statements that can split execution into several possible paths.
class Solution {
fun love(){
val message : String
message = "love" // Kotlin knows that `message` was not yet initialized
message = "hate" // Kotlin knows that `message` was yet initialized! It does not allow to modify the value.
}
}
Here is what Kotlin documentation says:
... it is also possible (but discouraged) to split the declaration and the initial assignment, and even to initialize in multiple places based on some condition. You can only read the variable at a point where the compiler can prove that every possible execution path will have initialized it. If you're creating a read-only variable in this way, you must also ensure that every possible execution path assigns to it exactly once.
Example of an execution path
Using when or if statement you create two or more execution paths. Execution paths can be presented as a graph, I'll use #number as a node number. Example:
class Solution {
fun love(){
// #1
val message : String
if (System.currentTimeMillisec() % 2 == 0) {
message = "Not empty"
// #2
}
if (message.isEmpty) { // Error! Message could be not initialized at this point!
println("Empty message")
// #3
}
}
}
Looking at this example, that does not compile, we can calculate at least 3 execution paths.
#1 (none of the if statements was entered. All conditions are false)
#1 -> #2
#1 -> #3
Kotlin can calculate these paths and check if the message variable is initialized in every path it is used. As we can see, as soon as you reach the evaluation of the second if statement (in case of first and third paths) your program will crash because the message has no value. It has no address in memory and a computer which runs this program does not know how to get a value from an address that does not exist.
Now, let's modify this code to make it work:
class Solution {
fun love(){
// #1
val message : String
if (System.currentTimeMillisec() % 2 == 0) {
message = "Not empty"
// #2
} else {
message = ""
// #3
}
if (message.isEmpty) { // Error! Message could be not initialized at this point!
println("Empty message")
// #4
}
}
}
Execution paths:
#1 -> #2
#1 -> #3 -> #4
In this example, Kotlin is sure that the message read-only variable is initialized because there is a 100% chance that one of node 2 or node 3 will be executed. Right after the line where the message gets its initial value (initialized) Kotlin treats this variable as a read-only variable with a value.
Questions are welcome. I will try to simplify this answer.

Golang test mock functions best practices

I am developing some tests for my code (using the testing package), and I am wondering what's the best way to mock functions inside the tested function:
Should I pass the function as parameter?
In that case, what if that function calls another function? Should I pass both the first and second function as parameters in the tested one?
Note: some of the functions are called on objects (i.e. someObj.Create()) and use HTTP API calls.
UPDATE for clarification:
Example: functions
func f1() error {
... //some API call
}
func (s *SomeStruct) f2() error {
return f1
}
func f3() error {
return nil
}
func f4() error {
...
err = obj.f2()
...
err = f3()
...
}
For the above: if I want to test f4, what's the best way to mock f2 and f3?
If I pass f2 and f3 to f4 as parameters it would work, but then what for the f2 test? Should I pass f1 to f2 as parameter?
And if that's it, should then f4 have f1 as well in the parameters?
As a general guideline, functions aren't very mockable so its in our best interests to mock structs that implement a certain interface that may be passed into functions to test the different branches of code. See below for a basic example.
package a
type DoSomethingInterface interface {
DoSomething() error
}
func DoSomething(a DoSomethingInterface) {
if err := a.DoSomething(); err != nil {
fmt.Println("error occurred")
return
}
fmt.Println("no error occurred")
return
}
package a_test
import (
"testing"
"<path to a>/a"
)
type simpleMock struct {
err error
}
func (m *simpleMock) DoSomething() error {
return m.err
}
func TestDoSomething(t *testing.T) {
errorMock := &simpleMock{errors.New("some error")}
a.DoSomething(errorMock)
// test that "an error occurred" is logged
regularMock := &simpleMock{}
a.DoSomething(regularMock)
// test "no error occurred" is logged
}
In the above example, you would test the DoSomething function and the branches that happens eg. you would create an instance of the mock with an error for one test case and create another instance of the mock without the error to test the other case. The respective cases are to test a certain string has been logged to standard out; in this case it would be "error occurred" when simpleMock is instantiated with an error and "no error occurred" when there simpleMock is not instantiated with an error.
This can of course be expanded to other cases eg. the DoSomething function actually returns some kind of value and you want to make an assertion on the value.
Edit:
I updated the code with the concern that the interface lives in another package. Note that the new updated code has a package a that contains the interface and the function under test and a package a_test that is merely a template of how to approach testing a.DoSomething.
I'm not sure what you're trying to do here but I'll explain how testing should be done in Go.
Lets say we have an application with the following directory hierarchy:
root/
pack1/
pack1.go
pack1_test.go
pack2/
pack2.go
pack2_test.go
main.go
main_test.go
We'll assume that pack2.go has the functions you want to test:
package pack2
func f1() error {
... //some API call
}
func (s *SomeStruct) f2() error {
return f1
}
func f3() error {
return nil
}
func f4() error {
...
err = obj.f2()
...
err = f3()
...
}
Looks good so far. Now if you want to test the functions in pack2, you would create a file called pack2_test.go. All test files in go are named similarly (packagename_test.go). Now lets see the inside of a typical test for a package (pack2_test.go in this example):
package pack2
import (
"testing"
"fmt"
)
TestF1(*testing.T) {
x := "something for testing"
f1() // This tests f1 from the package "pact2.go"
}
TestF2(*testing.T) {
y := new(somestruct)
y.f2() // tests f2 from package "pact2.go"
}
TestF3(*testing.T) {
/// some code
f3() // tests f3
}
TestF4(*testing.T) {
/// code
f3() // you get the gist
}
Let me explain. Notice how in pack2_test.go, the first line says that the package is pack2. In a nutshell, this means that we're in the "scope" of the package pack2 and thus all the functions found in pack2 can be called as if you're within pack2. Thats why, within the Testf* functions, we could've called the functions from pack2. Another thing to note is the imported package "testing". This helps with two things:
First, it provides some functionality for running tests. I won't go into that.
Second, it helps identify the functions that go test should run.
Now to the functions. Any function within a test package that has the prefix "Test" and the parameters "t *testing.T" (you can use "*testing.T" when you don't need to use the testing functionality) will be executed when you run go test. You use the variable t to reference the testing functionality I mentioned. You can also declare functions without the prefix and call them within the prefixed functions.
So, if I go to my terminal and run go test, it will execute the functions you want to test, specified in pack2_test.go
You can learn more about testing here and here