【问题标题】:java.lang.IllegalArgumentException: No DataSource specified Junit and Mockitojava.lang.IllegalArgumentException:未指定数据源 Junit 和 Mockito
【发布时间】:2019-02-08 09:30:13
【问题描述】:

早安各位! 我正在我的 Spring Boot 应用程序中进行单元测试,但它会启动下一个异常: java.lang.IllegalArgumentException:未指定数据源;

这是我的方法:

@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;
}

这是我的测试:

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);
}

有人知道我做错了什么吗?

PD:对不起我的英语,我是西班牙人!

【问题讨论】:

    标签: java spring testing junit mocking


    【解决方案1】:

    您正在尝试测试一个类,该类使用 bean 而不启动 Spring 的应用程序上下文。

    有多种方法可以解决您的问题。

    1. 让 spring 运行应用程序上下文。您可以通过在测试类中添加:@SpringBootTest@RunWith(SpringRunner.class) 注释来做到这一点。像这样:
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class controladorTest {
    ...
    }
    

    这样会创建 Spring 应用程序上下文 - 但您不必模拟控制器实例 - 因为它已经创建 - 所以您可以自动装配它:

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

    并删除下一行:

    static controlador mockInstanced;
    
    @BeforeClass
    public static void setup() throws Exception {
        mockInstanced= new controlador();
        mockInstanced.conn = mock(JdbcTemplate.class);
    }
    
    1. 另一种理论上的方法是模拟 JdbcTemplate 并使用 @InjectMocks 将其注入到您的模拟中 - 但我不建议这样做 - 太麻烦和脆弱的解决方案。
    2. 另外,考虑到您的控制器仅使用 JdbcTemplate 作为依赖项,您可以使用嵌入式 DB for Junit 并手动创建 JdbcTemplate 并将其注入您的控制器 - 在这种情况下,没有需要创建应用程序上下文,您可以手动创建一个控制器实例并将 JdbcTemplate 传递给它。请参阅this 了解更多信息

    所以在第 1 步之后,您的代码应如下所示:

    @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);
        }
    }
    

    顺便说一下,请查看Java naming conventions - 让您的代码更具可读性。

    更多关于使用 spring 测试的信息here

    【讨论】:

    • 嗨@Edu Martinez,如果这个或任何答案已经解决了您的问题,请考虑通过单击复选标记接受它。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
    猜你喜欢
    • 1970-01-01
    • 2019-05-24
    • 2013-11-10
    • 2016-08-19
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多