Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock a callback

Tags:

java

mockito

I'm trying to test a 3rd party library that works with a callback.

Db db;
db.find("param", new DbCallback() {
   public void onComplete(Result r) {
     //my business logic with r
     r.get("name"); //etc
   }
});

This is inside class Foo which is my test subject. It looks like this:

class Foo {

   @Autowired
   Db db;

   void bar() {
    db.find("param", new DbCallback() {
       public void onComplete(Result r) {
           // my business logic with r
           r.get("name"); //etc
       }
    });
  }
}

My test so far looks like this:

class FooTest {
  @InjectMocks
  Foo foo; // test subject

  @Mock
  Db db; //thing I want to mock

  // initMocks etc. 

  @Test
  void bar() {
    when(db.find( ??? )).then???
    foo.bar();
    // asserts etc. 
  }
}

But I'm not entirely sure how to use when here.

If it was a "regular" method I would just use

when(db.find(anyString()).thenReturn(fakeData)

like image 280
OscarRyz Avatar asked Feb 17 '26 16:02

OscarRyz


1 Answers

As long as you use Spring components, I highly recommend limiting yourself to mocking or spying beans using specific Spring Test annotations using Mockito through the Spring package org.springframework.boot.test.mock.mockito. A nice example is seen on JavaDoc of @MockBean. Translated to your code sample:

@MockBean    // this annotation creates a mock bean in Spring context
Db db;       // thing I want to mock

@Autowired   // injected as usual with the preference of mocked beans dependencies
Foo foo;     // test subject

Of course the test-class annotation differs for each version of jUnit used:

  • jUnit 4: @RunWith(SpringJUnit4ClassRunner.class)
  • jUnit 5: @ExtendWith(SpringExtension.class)

Back to your question, the when-then construct becomes fairly simple. Using static methods of Mockito class you are able to define what object types should be present as method parameters (either "any" value of a type or a specific value).

It also depends whether the method Db#find is void or has a return type.

  • The method has a return type:
    // the data object doesn't need to be a mock
    DbFindMethodReturnType mockData = new DbFindMethodReturnType(...); 
    
    Mockito.when(db.find(
                Mockito.eq("params"),            // Mockito.anyString() for any string
                Mockito.any(DbCallback.class)))  // Mockito.any() is also possible
           .thenReturn(mockData)
    
  • The method is void:
    Mockito.doNothing()
           .when(db)
           .find(Mockito.eq("params"), Mockito.any(DbCallback.class));
    
like image 95
Nikolas Charalambidis Avatar answered Feb 20 '26 04:02

Nikolas Charalambidis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!