1

Good Morning people! I am doing unit test in my spring boot application but it launches the next exception: java.lang.IllegalArgumentException: No DataSource specified;

This is my method:

@RestController public class controlador { @Autowired(required = true) JdbcTemplate conn; @CrossOrigin @RequestMapping(value = "/getlistadopantallatab", method = RequestMethod.POST, consumes="application/json",produces = "application/json") @ResponseBody public Map<String, Object> getListadoPantallaTab(@RequestBody Map<String,Object> dto) { Map<String, Object> simpleJdbcCallResult = null; try { SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(conn) .withCatalogName("CCR_PACKAGE") .withProcedureName("getListadoPorPantallaTab"); SqlParameterSource in = new MapSqlParameterSource(dto); simpleJdbcCallResult = simpleJdbcCall.execute(in); } catch (Exception e) { System.out.println("Se ha lanzado la siguiente excepcion: " + e); } return simpleJdbcCallResult; } 

and it is my test:

public class controladorTest { static controlador mockInstanced; @BeforeClass public static void setup() throws Exception { mockInstanced= new controlador(); mockInstanced.conn = mock(JdbcTemplate.class); } /** * Test of getListadoPantallaTab method, of class controlador. */ @Test public void testGetListadoPantallaTab() { System.out.println("Test unitario getListadoPantallaTab: "); @SuppressWarnings("serial") Map<String, Object> dto = new HashMap<String, Object>() {{ put("Inicio", 1); put("fin", 15); }}; mockInstanced.getListadoPantallaTab(dto); } 

Somebody knows what i am doing wrong?

PD: Sorry for my english, i am spanish!

1 Answer 1

1

You are trying to test a class, which uses beans without starting the Spring's application context.

There are multiple ways to solve your problem.

  1. Make spring to run application context. You can do that by adding: @SpringBootTest and @RunWith(SpringRunner.class) annotations to your test class. Something like this:
@SpringBootTest @RunWith(SpringRunner.class) public class controladorTest { ... } 

This way the Spring application context will be created - but you don't have to mock your controller instance - as it's already created - so you can just autowire it:

@SpringBootTest @RunWith(SpringRunner.class) public class controladorTest { @Autowired private controlador controlador; ... } 

and remove next lines :

static controlador mockInstanced; @BeforeClass public static void setup() throws Exception { mockInstanced= new controlador(); mockInstanced.conn = mock(JdbcTemplate.class); } 
  1. Another theoretical way is to mock JdbcTemplate and inject it into your mock using @InjectMocks - but I wouldn't recommend to do it - too cumbersome and fragile solution.
  2. Also, taking into account, that your controller uses only JdbcTemplate as a dependency, you can use an embedded DB for Junit and create the JdbcTemplate manually and inject it to your controller - in this case, there is no need to create the application context and you can just manually create a controller instance and pass JdbcTemplate to it. See this for more info

So after step 1, your code should look like the following:

@SpringBootTest @RunWith(SpringRunner.class) public class controladorTest { @Autowired private controlador controlador; /** * Test of getListadoPantallaTab method, of class controlador. */ @Test public void testGetListadoPantallaTab() { System.out.println("Test unitario getListadoPantallaTab: "); @SuppressWarnings("serial") Map<String, Object> dto = new HashMap<String, Object>() {{ put("Inicio", 1); put("fin", 15); }}; controlador.getListadoPantallaTab(dto); } } 

By the way, please look at Java naming conventions - to make your code more readable.

More info about testing with spring here

Sign up to request clarification or add additional context in comments.

1 Comment

Hi @Edu Martinez, if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.