0

I am creating an adapter web service that has configuration (codes below). I am able to mock the 'app' object but its attribute 'datasource' is null even I have mocked it. How can I mock the data source and its connection attribute?

MyAdapter.java

public class MyAdapter {

 @Context
 private ConfigurationAPI configApi;

 @Context
 private AdaptersAPI adaptersAPI;

 public Connection getSQLConnection() throws SQLException {

    JavaAdapter app = adaptersAPI.getJaxRsApplication(JavaAdapter.class);
    return app.getDataSource().getConnection();
   }
}

MyAdapterTest.java

     @RunWith(PowerMockRunner.class);
     public class MyAdapterTest {

         @Mock
         DataSource dataSource;

         @Mock
         private ConfigurationAPI configApi;

         @Mock
         private AdaptersAPI adaptersAPI;

         @InjectMocks
         MyJavaAdapter myAdapter;

         private MyApp app = new MyApp();

         @Test
         public void getSQLConnectionTest() throws SQLException {

     PowerMockito.when(adaptersAPI.getJaxRsApplication(JavaAdapter.class).thenReturn(app);
     PowerMockito.when(app.getDataSource()).thenReturn(dataSource);
           }
        }

MyApp.java

 public class MyApp extends MFPJAXRSApplication{


    private DataSource dataSource = null;

    @Override
    protected void init() throws Exception {

        InitialContext ctx = new InitialContext();
        dataSource = (DataSource) ctx.lookup("customPath");
    }

    @Override
    protected void destroy() throws Exception {

    }

    @Override
    protected String getPackageToScan() {
        return getClass().getPackage().getName();
    }

    public DataSource getDataSource() {
        return dataSource;
    }
Yejin
  • 541
  • 2
  • 15
  • 32
  • Where do you mock your `app` object? And what it's classes code look like? – Vüsal Feb 15 '19 at 08:17
  • Hi @Vusal, apology, I have forgot to paste my code. app is a MyApp.java class and it contains code above. – Yejin Feb 15 '19 at 08:23

2 Answers2

1

Try to reaplace this:

private MyApp app = new MyApp();

with this:

@InjectMocks
private MyApp app;
Vüsal
  • 2,580
  • 1
  • 12
  • 31
0

You cannot set the mock instances on the objects that are not mocked (You can set them by calling the setter methods though). Instead try to mock MyApp

@Mock
private MyApp app

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

Then you can use the below statement to mock the DataSource

PowerMockito.when(app.getDataSource()).thenReturn(dataSource);
Prasann
  • 1,263
  • 2
  • 11
  • 18
  • It seems that you lack basic knowledge here. He is already using the PowerMockitoRunner, so there is no need to call initMocks(). The part about mocking the correct object is correct, but only half of what is required here. – GhostCat Feb 20 '19 at 11:18
  • As you see he is using `@InjectMocks` to inject the mocks on `MyJavaAdapter` and `@InjectMocks` internally creates them. Refer to https://stackoverflow.com/a/16467893/1036310. I am suggesting to initialize the mocks to use within the junit class itself and if you don't initialize the mocks, they will be null in the test class – Prasann Feb 21 '19 at 13:31
  • But well, your answer doesn't say that ... and as said: that initMocks() itself, that doesn't add anything. – GhostCat Feb 21 '19 at 14:59
  • Well, as I mentioned `setUp` methods and the way to mock the `dataSource`, it should be self-explanatory that it should be added to test class. I think this should be clear to the users now with our conversation :) – Prasann Feb 22 '19 at 10:03