Access to h2 web console while running junit test in a Spring application
Asked Answered
E

6

35

I'm building a Spring application and I need to inspect my H2 in-memory database while I'm running my JUnit tests from a web browser.

In my Spring configuration I have a bean which is responsible of creating my database schema and populating it with some data which will be used within my JUnit tests. I've also added a bean in my test context which creates a web server where I eventually will look for my data.

<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
    factory-method="createWebServer" init-method="start" lazy-init="false">
    <constructor-arg value="-web,-webAllowOthers,-webPort,11111" />
</bean>

Everything seems ok because the database is populated properly since I can access to its data from my JUnit tests and H2 Server only runs while I'm in my test-phase (I can know that, because if I try to access to my_ip:111111 before debugging my tests I cannot connnect but I can connect afterwards once I've started my tests).

Anyway If I open my H2 console from a web browser no schema is shown in it. Any ideas??

Many thanks!!

Essayistic answered 12/9, 2012 at 14:10 Comment(4)
What does your jdbcUrl in unit tests look like?Viol
Hi Michael, thank you for your answer. My jdbc URL looks like jdbc:h2:mem:my_DB;DB_CLOSE_DELAY=-1;MODE=Oracle I've also tried to add the IFEXIST property in the jdbc URL just in case that could help me. It couldn't :(Essayistic
Hello @Ivan Fernandez can you let us know how you have solved this problem ? I am facing the same issue. You answer is much appreciated. Thanks !!Plourde
Were you able to resolve the issue ?Honghonied
H
58

As this is probably going to be a test-debugging feature, you can add it at runtime with your @Before:

import org.h2.tools.Server;

/* Initialization logic here */

@BeforeAll
public void initTest() throws SQLException {
    Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082")
    .start();
}

And then connect to http://localhost:8082/

Note: unless you need this to run as part of your CI build, you'll need to remove this code when you're finished debugging

Herrod answered 3/12, 2015 at 14:35 Comment(4)
If you have not provided connection URL, then the you could connect to h2 db from the console using default URL jdbc:h2:mem:dataSourceNehemiah
It was better to use BeforeClass instead of BeforeKerato
Can we observe "jdbc:h2:mem:test" in memory H2 DB using the web console?Effluence
A little tip, if using idea to debug, make the breakpoint suspend type to "Thread", not "ALL", or the h2 console will hang.Falbala
S
6

For future reference here's another way to do it:

  1. Start database and web servers (version can differ):

    $ cd .../maven_repository/com/h2database/h2/1.4.194 $ java -cp h2-1.4.194.jar org.h2.tools.Server -tcp -web -browser TCP server running at tcp://169.254.104.55:9092 (only local connections) Web Console server running at http://169.254.104.55:8082 (only local connections)

  2. Set database url for tests in code to jdbc:h2:tcp://localhost:9092/mem:mytest.

  3. Run or debug tests.
  4. Click Connect in browser window which opened in step 1.

Jar file for H2 can be downloaded at https://mvnrepository.com/artifact/com.h2database/h2.

Server can be started via @Before in test file like in snovelli's answer, but only in case connection to database in established afterwards, which might be a problem.

Salicaceous answered 3/4, 2017 at 19:32 Comment(1)
This answer worked for me. I was running some junit test cases and I want to check monitor DB status and tables after test case run. Running H2 console explicitly worked for me.Bochum
D
4

@snovelli answer above is good. To debug a particular test case in your IDE, add a infinite loop at the end of the test case and go to browser and launch the console and you can query the data. Something like below

import org.h2.tools.Server;

/* Initialization logic here */

@BeforeAll
public void initTest() throws SQLException {
    Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082")
    .start();
}

@Test
void testMyDBOperation() {
    //some db operations like save and get
    while(true) {
    }
}

now you can go to browser and launch the console at http://localhost:8082/ Of course delete above two changes after debugging

Diva answered 6/4, 2022 at 15:24 Comment(0)
V
2

I guess the problem is that you are connecting to h2db directly from your application. Not through the server you are launching with bean. Because of this your app and h2db-web-interface can't share one in-memory database.

You should change jdbcUrl in tests to something like jdbc:h2:tcp://localhost/mem:my_DB;DB_CLOSE_DELAY=-1;MODE=Oracle and in browser you should connect to the same url.

With jdbc urls like jdbc:h2:tcp://localhost/... all connections will go through the h2db-server and you can view database state in browser.

Viol answered 13/9, 2012 at 14:52 Comment(0)
D
2

If you have defined the jdbc url to something like jdbc:h2:mem:db in your properties, when the database is created it actually gets a bit longer name.

Add a @Autowired DataSource dataSource to your test class, set a debug point somewhere, and inspect that datasource with dataSource.getConnection() and look at the url property. In the case I'm running right this moment, it is

jdbc:h2:mem:43ed83d6-97a1-4515-a925-a8ba53cd322c

Plugging that into the web cosole shows everything I'm expecting.

It isn't the most straightforward way, but it does work.

Duplessis answered 19/8, 2021 at 15:52 Comment(0)
G
1

It is not the answer, but a debugging tip.

When you finally access h2-conole http://127.0.0.1:8082/ you may notice that database changes are not shown.

This is because the test cases are not transactional and the data is not committed. Although this behavior is good, as each test case, must run in predefined environment. It is not good if you want to debug and see database changes.

To achieve this, add @Commit annotation above test case and put a dummy line in a @AfterAll annotated method, to stop test and let you see the h2 console ( The h2 server will stop as the test finish).

@AfterAll
public static void finalizeTest() throws Exception  {
    System.out.print("Just put a break point here");
}  

@Test
@Commit
void should_store_an_article() {        
 // Your test here
}
Gailey answered 28/1, 2023 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.