12

I have a bug that manifest himself only when database is slow. It applies to even simplest database operations (select, etc).

I would like to create test, where I force my database to be slow. How to do that?
I use Spring Boot, Spring Data, Hibernate, MariaDB.

Ideally, I want the 'slow database' part to be completely contained in the test code, in my java application. That way, test will be completely automated and self-contained.

I want to slow down database access only for one test (not globally, for all access).

I was proposed to introduce database trigger (BEFORE SELECT) with sleep

But this is not flexible, because it slows down every access, not access just for one test.

8
  • 3
    The easy answer is to write a test repository class that has a Thread.sleep embedded in it. Commented Sep 7, 2016 at 13:00
  • @duffymo using Thread.sleep seems like a bad idea, almost like purposely slowing down but not knowing how much to slow down. Commented Sep 7, 2016 at 13:04
  • 2
    Bad idea? It's a test - that's the whole idea as I understand it. You could make it a random value over a range if you'd like. The point is that a degree of slowness that's associated with failure is known. Commented Sep 7, 2016 at 13:21
  • Thread.sleep for test only is good enough for me. Simple and does what's needed. Commented Sep 7, 2016 at 13:30
  • Some of the answers to this question might be of interest. Commented Sep 7, 2016 at 13:55

4 Answers 4

15

I see four possible solutions for this problem.

  1. You don't have to create slow database, you can create slow connection to the database. If you run database on a different (Virtual) machine, there are systems that help simulating shitty internet connections by delaying network responses randomly.

  2. You can use sleep(10) function that is provided by your database, this would require "injecting" it into SQL query or override method for the purpose of test and replace SELECT with SELECT SLEEP(10).

  3. Simulate stress-test on the database with mysqlslap if you use mysql.

  4. Another solution, a bit stupid tho, you can use spring-aop and attach a delay aspect before and after the DAO method execution with random small sleep. This way you have control over it, don't have to modify existing code and let spring make the job of doing the delay without integration into real-system. Not that stupid after all. This one is quite flexible and I think I would go with it. Easiest to setup.

If it's stupid, but it works, it's not stupid.

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

3 Comments

I like spring-aop solution most. It is easy to do this just for the test. Other solutions are more complex, have more moving parts that require manual setup. I do not mind writing a few lines of code- if my 'slow database' test will be fully automated.
@BartoszBilicki Depending what do you mean by one test, I think solution 4 is easy to setup and flexible. If your test is on selemium or tests something end-to-end it might not be the best, but definitely the easiest.
Right, solution 4 is suitable for junit test, that mocks part of the application. Is it not applicable for end-to-end test.
12

I had a similar need when developing on a SQL Server DB.

To simulate a slow query you can use (but this is specific to SQL Server):

select * from TABLE
WAITFOR DELAY '00:00:45'--to simulate 45 seconds of delay

Comments

1

If you want to write a Spring Boot Test, maybe you can use the @SpyBean annotation

   @SpyBean
   SomeBeanCallingTheDatabase someBeanCallingTheDatabase;

   //...
   // in the test method

   doAnswer(answer-> {
                Thread.sleep(300L); //any value here
                return answer.callRealMethod();
            })
    .when(someBeanCallingTheDatabase)
                .find(any());

   // call the service using the bean above

Comments

-2

The easy answer is to write a test repository class that has a Thread.sleep embedded in it.

credit: this answer was provided by https://stackoverflow.com/users/37213/duffymo in the comment.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.