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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.