1

I have the following code which I would like to mock. I'm basically interested in mocking the DataSourceTransactionManager.

    @Autowired
    @Qualifier("nesTransactionManager")
    DataSourceTransactionManager mDataSourceTransactionManager;

   ...............................

    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
       TransactionStatus status = mDataSourceTransactionManager.getTransaction(def);

       try {
          <-doing some DB operations here>
          mDataSourceTransactionManager.commit(status);
       } catch (Exception e) {
          mDataSourceTransactionManager.rollback(status);
       }
.............

So far I've tried this:

    @Mock
    private DataSourceTransactionManager mDataSourceTransactionManager;

   @Before
    public void runBeforeEachTest() {
        when(mDataSourceTransactionManager.getTransaction(any(DefaultTransactionDefinition.class))).thenReturn(null);
        doNothing().when(mDataSourceTransactionManager).commit(any(TransactionStatus.class));
        doNothing().when(mDataSourceTransactionManager).rollback(any(TransactionStatus.class));
}

And this:

    @Mock
    private DataSourceTransactionManager mDataSourceTransactionManager;

   @Before
    public void runBeforeEachTest() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

        when(mDataSourceTransactionManager.getTransaction(eq(def))).thenReturn(null);
        doNothing().when(mDataSourceTransactionManager).commit(any(TransactionStatus.class));
        doNothing().when(mDataSourceTransactionManager).rollback(any(TransactionStatus.class));

But I've always got this error:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at com.nuance.entrd.mc.nes.jobs.JobPollerTest.runBeforeEachTest(JobPollerTest.java:43)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.

    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:337)

Error which doesn't make any sense in this context. Any idea on how can I address this ?

Thanks

Yonoss
  • 1,242
  • 5
  • 25
  • 41
  • Note that the error is generated at the when line – Yonoss Aug 04 '15 at 11:23
  • So you're creating a mock in your test. Your stubbing does nothing. But more importantly, how are you injecting that mock into the class that you're testing? – Dawood ibn Kareem Aug 04 '15 at 11:30
  • Well, i have a setter for that : jobPoller.setDataSourceTransactionManager(mDataSourceTransactionManager); But again, The error is being thrown before getting to that setter. – Yonoss Aug 04 '15 at 11:32
  • Can you show us your getTransaction() method? – Dawood ibn Kareem Aug 04 '15 at 11:42
  • It's the spring framework DataSourceTransactionManager.getTransaction() http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/transaction/support/AbstractPlatformTransactionManager.html#getTransaction(org.springframework.transaction.TransactionDefinition) – Yonoss Aug 04 '15 at 11:45
  • 2
    According to that documentation, that method is final. You can't stub a final method in Mockito. – Dawood ibn Kareem Aug 04 '15 at 11:47

3 Answers3

1

The way I've solved my problem was to use PowerMokito :

@RunWith(PowerMockRunner.class)
@PrepareForTest({DataSourceTransactionManager.class})
public class JobPollerTest {
.....................
 private DataSourceTransactionManager mDataSourceTransactionManager;
......................

    mDataSourceTransactionManager = PowerMockito.mock(DataSourceTransactionManager.class);

     DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

            Mockito.when(mDataSourceTransactionManager.getTransaction(def)).thenReturn(null);
Yonoss
  • 1,242
  • 5
  • 25
  • 41
0

The first step is to add the following line above your test class name.

@PrepareForTest(DataSourceTransactionManager.class)
public class yourTestName{

The second step is to add the mock as follows:

@Mock
DataSourceTransactionManager dstManager;

Third step:

@Mock
TransactionStatus tranStatus;

Fourth step in the @test method please initialize as follows:

TransactionDefinition transDef=new DefaultTransactionDefinition();
Mockito.when(dstManager.getTransaction(transDef)).thenReturn(tranStatus);
Suraj
  • 11
  • 3
0

Mockito with final classes and methods

There are several things you can do to resolve your issue, and PowerMock is one of them:

Yevdo Abramov
  • 609
  • 4
  • 10