Mockito:How to Verify Method Was Called on an Object Created Within a Method

Mockito : how to verify method was called on an object created within a method?

Dependency Injection

If you inject the Bar instance, or a factory that is used for creating the Bar instance (or one of the other 483 ways of doing this), you'd have the access necessary to do perform the test.

Factory Example:

Given a Foo class written like this:

public class Foo {
private BarFactory barFactory;

public Foo(BarFactory factory) {
this.barFactory = factory;
}

public void foo() {
Bar bar = this.barFactory.createBar();
bar.someMethod();
}
}

in your test method you can inject a BarFactory like this:

@Test
public void testDoFoo() {
Bar bar = mock(Bar.class);
BarFactory myFactory = new BarFactory() {
public Bar createBar() { return bar;}
};

Foo foo = new Foo(myFactory);
foo.foo();

verify(bar, times(1)).someMethod();
}

Bonus: This is an example of how TDD(Test Driven Development) can drive the design of your code.

Mockito How to test that an instance created inside a method is calling methods

You have three alternatives:

  1. Using the injection
  2. Using PowerMockito
  3. Refactor the code in a test friendly manner

Using the injection

If the object Obj is injected in your class under test, instead of has been initialized in the method, you will be able to inject a mock and then use the expression

verify(obj).callsMethod()

that you already knew and that is right.

Using PowerMockito

With powermockito you can write something like this

@RunWith(PowerMockRunner.class)
@PrepareForTest({Obj.class})
class MyJunit{
....
@Test
public void test() throws Exception{
Obj myMock = Mockito.mock(Obj.class);
PowerMockito.whenNew(Obj.class).withAnyArguments().thenReturn(myMock);

// here your test
}

At this point you can use the expression you already knew and that is right.

Refactor

You can use a protected method in order to build th Obj and mock this method in your junit in order to return a mock version of the Obj and then use the expression you already knew and that is right.

Mockito: How to verify a method was called only once with exact parameters ignoring calls to other methods?

Mockito.verify(foo, Mockito.times(1)).add("1");
Mockito.verify(foo, Mockito.times(1)).add(Mockito.anyString());

The first verify checks the expected parametrized call and the second verify checks that there was only one call to add at all.

Mockito, how to verify if the method of the tested class was called?

You won't be able to use Mockito to verify that method is called, but you can verify the output from the getAll() method given that you've mocked out the response to dishRepository.findAll(). So, in effect, just add some assertions after your verify calls that match your expected data with the actual data, I assume that this::toDishResponseDTO just return a Dish.

@Test
void shouldCallFindAllReturnDto_whenV() {
Mockito.when(dishRepository.findAll()).thenReturn(TestData.ENTITY_DISH);
List<Dish> dishes = dishService.getAll();
Mockito.verify(dishRepository, times(1)).findAll();
assertThat(dishes, is(notNullValue());
assertThat(dishes.get(0).getSomeField, is(equalTo("someValue")));
}

How to use Mockito to verify a method is called in another method?

You can't use Mockito if you create a new ClassB instance in your method.

You should refactor publish() to take ClassB as a parameter, and then you can send your Mockito mock instead of a real ClassB, and verify on it.

Like so:

public class A {

public void publish(ClassB classb){
classb.sendRequest(this)
}
}

And in your test:

ClassB mockClassB = mock(ClassB.class);
A a = new A();
a.publish(mockClassB);

verify(mockClassB, times(1)).sendRequest(any());

How to verify a method inside a method is called in mockito

You mocked A and replaced it with MockA. Mocks have no implementation. MockA.doSomething() does nothing and does not and cannot call MockA.callMe().

That A.doSomething() calls A.callMe() should be considered an implementation detail of of doSomething(); making a test rely on that would tightly couple the test to the specific implementation and would be brittle.

You can't use a mock to verify the implementation of the thing being mocked. If you want to verify the implementation of A.doSomething(), you instead should use an actual object and verify observable properties on that object.

But if you still really want to do this, then you would need to modify A to not call methods on itself and to instead call methods on a provided object (i.e., "dependency injection"). For example:

class A {
final late A a;

A({A? a}) {
this.a = a ?? this;
}

void doSomething() {
a.callMe();
}

void callMe() {}
}

test("Test method is called", () {
var mockA = MockA();
var actualA = A(a: mockA);
actualA.doSomething();
verify(mockA.callMe()).called(1);
});

It's a bit unusual for a class to depend on a mock of itself, however, and it would not scale if you then want to verify calls made by callMe().

Another approach that would scale better (but with significantly more work) would be to create your own fake class that tracks method calls:

class TrackedA implements A {
int doSomethingCallCount = 0;
int callMeCallCount = 0;

@override
void doSomething() {
doSomethingCallCount += 1;
super.doSomething();
}

@override
void callMe() {
callMeCallCount += 1;
super.callMe();
}
}

But again, that's very brittle, and I would not recommend it.

Mockito - Verify if an object in a set called a method

You could simply invoke the verify on each mocked element of the Set :

for (MyType myType : myTypes) {
verify(myType, times(3))
.getName();
}

But this will not work with the actual code because myTypes is defined as a Mock :

@Mock
private Set<MyType> myTypes = (Set<MyType>) mock(Set.class);

And you didn't record any behavior for it.

So you could never iterate on elements added as elements will never be added in the Set as you do that :

MyType mT = Mockito.mock(MyType.class);
mT.setName("Name" + i);
myTypes.add(mT);

In fact myTypes has not to be a mock.

Declare it as a plain object :

private Set<MyType> myTypes = new HashSet<>();

You don't need to spy the object under test either.

You want to verify invocation of mocks, not invocations of the object under test.

So you can also replace :

TestObject testObject = Mockito.spy(new TestObject());

by :

TestObject testObject = new TestObject();

Note that spying is not a good practice but a workaround. So avoid that as you can and above all as you don't need it !

And it should be fine.



Related Topics



Leave a reply



Submit