Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Mockito's when() get triggered?

I need to test a service class, but when I try to mock the dao class, it doesn't get triggered, thus not able to use ThenReturn().

I think that the problem is because I use an interface for my Dao and @Autowired in the service class (Spring MVC 3.1):

The interface:

public interface TestDao {
    int createObject(Test test) throws NamingException;
}

The implementation:

@Repository
public class TestDaoImpl implements TestDao {

    @Override
    public int createObject(Test test) {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new InsertNewTest(test), keyHolder);
        return ((java.math.BigDecimal)keyHolder.getKey()).intValue();
    }
}

The service:

public class RegTest {
    @Autowired
    TestDao testDao;

    public int regTest(int .....) {
        .
        .
        int cabotageId = testDao.createObject(test);
    }
}

In the test I have:

@RunWith(MockitoJUnitRunner.class)
public class TestRegService {
    @InjectMocks
    private RegTest regTest = new RegTest();

    @Mock
    TestDao testDao;

    @Test()
    public void test() {
        .
        when(testDao.createObject(null)).thenReturn(100);
        .
    }

testDao.createObject(null) returns 0 (due to being mock'ed) and not 100 as I is trying to achieve.

Can anybody help, please?

Problem solved!

It was the passing test-object to createObject() that did not match. Using

testDao.createObject(any(Test.class))

did the trick!

like image 227
mamruoc Avatar asked May 18 '26 11:05

mamruoc


2 Answers

If your test is actually passing a value to createObject, then when(testDao.createObject(null)... never gets matched. Rather than matching on null, you could match any instance of Test with testDao.createObject(any(Test.class))...

Also when you tried later to supply new Test() as the argument to match, it will literally try to match on that exact instance of Test, but presumably your real code is new-ing up a different one. So the use of Matchers.any(Test.class) as the parameter to match is the way to go.

like image 151
Kevin Welker Avatar answered May 20 '26 17:05

Kevin Welker


Mockito injection mechanism don't know about Spring @Autowired or CDI @Inject annotations. It just tries to find the best candidate given the type and the name of the mock, and it can lookup private fields too. See the javadoc of @InjectMocks : http://docs.mockito.googlecode.com/hg/1.9.0/org/mockito/InjectMocks.html

The semantic you are using is correct, though if you are experiencing issues, I would rather look for incorrect interactions or incorrect arguments.

Are you sure the test variable in regTest.regTest(int...) is really null when passed to testDao.createObject(test) ?

like image 38
Brice Avatar answered May 20 '26 18:05

Brice



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!