Search code examples
javadatabasejunitsql-insertsql-delete

Testing class that insert, update and delete from the db


I have class that has 3 methods: insert, update and delete from the db. In order to test it in the insert test method I need to use the insert method and after I insert i need to delete what I inserted, but in order to delete I should use the delete method that I also want to test so it didn't make sense to me that I need to use them and also test them.

I hope you understand my problem. Thanks in advance!


Solution

  • You must decide what you want to test. That was you describe, it is an integration test. By a “real” unitTest, you test only your method, and not the System method and not the database.

    If you want a unitTest, you have several options. For Example, you work with interfaces and catch your statement before it comes to the database.

    Edit 1 - one possibility to implement unit test with interfaces:

    You need one interface that implements the method these go to the backend system:

    public interface IDatabase{
    
        public returnValue insert(yourParam);
    
        public int update(yourParam);
    
    }
    

    Then you implement your method with the real functions in a class:

    public class Database implements IDatabase {
    
        @Override
        public returnValue insert(yourParam) {
            // do something
            return null;
        }
    
        @Override
        public int update(yourParam){
            // do something
            return 0;
        }    
    }
    

    This class you call in the main class:

    /**
     * The real class to do what you want to do.
     */
    public class RealClass {
    
    private IDatabase dbInstance = null;
    
        private IDatabase getDbInstance() {
            if (dbInstance == null) {
                dbInstance = new Database();
            }
            return dbInstance;
        }
    
        protected void setDbInstance(IDatabase dataBase) {
            dbInstance = dataBase;
        }
    
        public static void main(String[] args) {
            getDbInstance().insert(yourParam);
    
        }
    }
    

    For the unit test you implement the interface again:

    public class UnitTest implements IDatabase {
    
        @Override
        public returnValue insert(yourParam) {
            // Here can you test your statement and manipulate the return value
            return null;
        }
    
        @Override
        public int update(yourParam){
            if (yourParam.containsValue(value1)) {
              assertEquals("yourStatement", yourParam);
              return 1;
            }else if (yourParam.containsValue(value2)) {
              assertEquals("yourStatement2", yourParam);
              return 5;
            }else{
               assertTrue(false,"unknown Statement")
            }
        }
    
        @Test
        public void yourTest(){
           RealClass.setDbInstance(this);
            //Test something
        }        
    }
    

    This is time-consuming to implement, but with this, you are independent from the backend system and you can call the unittest every time without a database.

    enter image description here