Cast exception when mocking kotlin lambda callbacks in Mockk - unit-testing

I am having some trouble mocking callback functions with Mockk.
I am trying to mock a task success listener that is called like this:
collection
.add(Item())
.addOnSuccessListener {
update(collection.document(it.id))
}
Where the java signature for the callback would look like this:
public interface OnSuccessListener<T> {
void onSuccess(T var1);
}
and the signature for addOnSuccessListener looks like this
public abstract Task<DocumentReference> addOnSuccessListener(#NonNull OnSuccessListener<DocumentReference> var1);
My mock looks like this:
every { documentReferenceTask.addOnSuccessListener(any()) } answers {
firstArg<(DocumentReference) -> Unit>().onSuccess(documentReference)
value
}
I have also tried:
every { documentReferenceTask.addOnSuccessListener(any()) } answers {
firstArg<OnSuccessListener<DocumentReference>>().invoke(documentReference)
value
}
Either way, I am receiving a cast exception like:
java.lang.ClassCastException: com.package.MyClass$addProduct$1 cannot be cast to kotlin.jvm.functions.Function1

Oops, I was misreading the error.
every { documentReferenceTask.addOnSuccessListener(any()) } answers {
firstArg<OnSuccessListener<DocumentReference>>().invoke(documentReference)
value
}
This method works, the cast exception was from the second line. The correction looks like
every { documentReferenceTask.addOnSuccessListener(any()) } answers {
firstArg<OnSuccessListener<DocumentReference>>().invoke(documentReference)
**documentReferenceTask**
}

Related

Mock a scheduleWithFixedDelay method using EasyMock

How can I mock the start() function in the following code using easyMock?
class A {
public runOnce(Integer a) {
// do something
}
public void start() {
executor.scheduleWithFixedDelay(() -> runOnce(12), 0, 1000, TimeUnit.MILLISECONDS);
}
}
I tried in the following way which is not working:
ScheduledExecutorService executorService = createMock(ScheduledExecutorService.class);
executorService.scheduleWithFixedDelay(anyObject(), eq(0), eq(1000), eq(TimeUnit.MILLISECONDS));
expectLastCall().andReturn(null);
A a = createMockBuilder(A.class).addMockedMethod(A.class.getDeclaredMethod("runOnce", Integer.class)).createMock();
a.runOnce(12);
expectLastCall();
replay(executorService);
a.start();
verify(executorService);
Can someone suggest how can I fix it?
I see two problems here. First, you are not injecting the mocked executorService into your A instance. I will assume you can use a constructor to do that.
A a = createMockBuilder(A.class)
.addMockedMethod(A.class.getDeclaredMethod("runOnce", Integer.class))
.withConstructor(executorService)
.createMock();
Then, matchers need to take the correct types in parameter. So here scheduleWithFixedDelay expects long. So the expect should be
expect(executorService.scheduleWithFixedDelay(anyObject(), eq(0L), eq(1000L), eq(TimeUnit.MILLISECONDS)))
.andReturn(null);
Doing this makes everything run smoothly.

TypeScript Generic Collection: List

I am trying to learn TypeScript, and need some advice on implementing generic collection types. I put the dictionary and HashSet in another question, here I'd like any advice on my list type.
Especially the ForEach-Operation looks a bit strange. I think I found it in another question here, and "improved" by returning true or false to give feedback if the iteration was stopped early or completed.
import { IForEachFunction } from "./IForEachFunction"
export class List<T> {
private _items: Array<T>;
public constructor() {
this._items = [];
}
public get Count(): number {
return this._items.length;
}
public Item(index: number): T {
return this._items[index];
}
public Add(value: T): void {
this._items.push(value);
}
public RemoveAt(index: number): void {
this._items.splice(index, 1);
}
public Remove(value: T): void {
let index = this._items.indexOf(value);
this.RemoveAt(index);
}
public ForEach(callback: IForEachFunction<T>): boolean {
for (const element of this._items) {
if (callback(element) === false) {
return false;
}
}
return true;
}
}
The ForEach-Iteration relies on an interface from another file:
export interface IForEachFunction<T> {
(callback: T): boolean | void;
}
You would use my list and the ForEach-Method like this:
let myList: List<a_type> = new List<a_type>();
let completed: boolean = myList.ForEach(xyz => {
// do something with xyz
return false; // aborts the iteration
return true; // continues with the next element
});
if (completed) // we can see what happened "during" the iteration
I think this is not bad, but I'd appreciate any input. I am not sure if I use the === correctly.
Another question which I really like to know: How could I define a function with the interface IForEachFunction? I do not really "re-use" that interface visibly, I always declare an anonymous method as shown above. If I wanted to call a method having the interface definition, is that possible?
Thanks!
Ralf
One problem I see is that you have an interface instance:
callback: IForEachFunction<T>
This contains a method called
callback()
But you only call callback once. You would have call callback() method inside your interface:
callback.callback()
Also your code looks like it is inspired by C# or Java. In TypeScript you would often just use an array. This simplifies certain code constructs.

Understanding how to do JUnit testing with Mockito doReturn/when for the methods with return type void

Suppose, I have a test class with two methods as follows:
public class TestClass {
#Mock
TestClass testObject;
#Test
public void method1() {
doReturn("str").when(testObject).method2();
String s1 = testObject.method2(); // This line gives compilation
//error. Type mismatch cannot convert from void to string
}
#Test
public void method2() {
}
I am basically trying to mock method2 which is a dependency in method1.
But as you can see, the method2 return type is void. So, I am using doReturn to mock it.
As far as my understanding goes, although the method2 's return type is void, after I mock it, the mocked version of method2 should return String type.
But, as I have commented in method1, it is giving type mismatch.
You are simply getting mocking wrong.
Mocking means: instead of create "real" objects of a specific class, you create a stub/dummy/mock that looks like an object of that class. But in reality - it is not.
Beyond that: mocking can not change the signature of a method. So your idea that you could somehow use mocking to have a void method return something is wrong.
You are simply going down the wrong rabbit hole - what you intend to is not possible.
I think you're using the wrong method. doReturn allows you to "inject" the result of the execution. If you want to "falsify" the whole method execution you should consider using doAnswer:
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
// whatever you want to execute here...
// Simply return null
return null;
}
}).when(testObject).method2();

Method with argument of AbstractController phpunit. Any hints

I need to test method which looks like this, but my question is: How i should enter this method especially when i can not "mock" AbstractController, and without variable of AbstractController it would not work
public function add(\Queue\Controller\AbstractQueueController $task)
{
//Logic of method
}
You don't need to mock it. You already set it as a parameter, so this test is not about testing AbstractQueueController.
So, for example, if your function looks like this :
public function add(\Queue\Controller\AbstractQueueController $task)
{
$task->doSomething();
}
Then, in the test,AbstractQueueController should receive a call to doSomething method(), and then assert the result of that.
well i did something like that i made extended class
class addtest extends Queue\Controller\AbstractQueueController
{
public function task()
{
}
}
and then in my QueeuServiceTest extended by PHPUnit_framework_TestCase
i made testmethod
public function testadd()
{
$this->queueService->add(new addtest);
}
it covers code but i do not know it is good practice

Golang: Replace function unit testing

I'm working with Golang, and currently I'm doing some fun unit test with Testify, my file look like this
type myStruct struct {
field_1 string
}
func (self *myStruct) writeFirst() {
//doing something
//modify field_1
self.writeSecond()
}
func (self *myStruct) writeSecond() {
//doing something
}
In this case I'm testing writeFirst() but I'm trying to replace writeSecond() because it is using http stuff that I don't want to use because it access to internet.
I think that use a second struct and set myStruct as anonymous field will be the solution, but it's not working because me second struct and myStruct have a diferent context.
In this case I can't use mocks cause writeSecond is a method of the struct.
My test case looks like this:
func TestWriteFirst(t *testing.T) {
myStc := myStruct{}
assert.Equal(t,"My response", myStc.field_1)
}
All that I want is testing writeFirst without pass to writeSecond()
To illustrate the kind of refactoring mentioned by Not-a-Golfer in the comments, you could consider calling your second function only on an instance that is an interface:
type F2er interface {
Func2()
}
type S struct{ _f2 F2er }
var s = &S{}
func (s *S) f2() F2er {
if s._f2 == nil {
return s
}
return s._f2
}
func (s *S) Func1() {
fmt.Println("s.Func1")
s.f2().Func2()
}
Here: Func1 calls Func2 on s.f2(), not directly s.
If nothing has been set in s, s.f2() returns... itself: s
if s._f2 was replaced by any other struct which implements Func2, s.f2() returns that instance instead of itself.
See a complete example in this playground script.
Output:
TestFunc1
s.Func1
s.Func2
TestFunc1bis
s.Func1
testS.Func2 <=== different Func2 call