tags:

views:

123

answers:

4

I have not used Junit before and have not done unit testing automatically.

Scenario: We are changing our backend DAO's from Sql Server to Oracle. So on the DB side all the stored procedures were converted to oracle. Now when our code calls these thew Oracle Stored Procedures we want to make sure that the data returned is same as compared to sql server stored procedures.

So for example I have the following method in a DAO:

  //this is old method. gets data from sql server
  public IdentifierBean getHeadIdentifiers_old(String head){
      HashMap parmMap = new HashMap();
      parmMap.put("head", head);
      List result = getSqlMapClientTemplate().queryForList("Income.getIdentifiers", parmMap);
      return (IdentifierBean)result.get(0);
   }
  //this is new method. gets data from Oracle  
  public IdentifierBean getHeadIdentifiers(String head){
      HashMap parmMap = new HashMap();
      parmMap.put("head", head);
      getSqlMapClientTemplate().queryForObject("Income.getIdentifiers", parmMap);
      return (IdentifierBean)((List)parmMap.get("Result0")).get(0);
   }

now I want to write a Junit test method that would first call getHeadIdentifiers_old and then getHeadIdentifiers and would compare the Object returned (will have to over-write equals and hash in IdentifierBean). Test would pass only when both objects are same.

In the tester method I will have to provide a parameter (head in this case) for the two methods..this will be done manually for now. Yeah, from the front end parameters could be different and SPs might not return exact results for those parameters. But I think having these test cases will give us some relief that they return same data...

My questions are:

  • Is this a good approach?
  • I will have multiple DAO's. Do I write the test methods inside the DAO itself or for each DAO I should have a seperate JUnit Test Class?
  • (might be n00b question) will all the test cases be ran automatically? I do not want to go to the front end click bunch of stuff so that call to the DAO gets triggered.
  • when tests are ran will I find out which methods failed? and for the ones failed will it tell me the test method that failed?
  • lastly, any good starting points? any tutorials, articles that show working with Junit
A: 

G'day,

Here's a quick yet fairly thorough intro to JUnit

HTH

cheers,

Rob Wells
+3  A: 

Okay, lets see what can be done...

Is this a good approach?

Not really. Since instead of having one obsolete code path with somewhat known functionality, you now have two code paths with unequal and unpredictable functionality. Usually one would go with creating thorough unit tests for legacy code first and then refactor the original method to avoid incredibly large amounts of refactoring - what if some part of your jungle of codes forming the huge application keeps calling the other method while other parts call the new one?

However working with legacy code is never optimal so what you're thinking may be the best solution.

I will have multiple DAO's. Do I write the test methods inside the DAO itself or for each DAO I should have a seperate JUnit Test Class?

Assuming you've gone properly OO with your program structure where each class does one thing and one thing only, yes, you should make another class containing the test cases for that individual class. What you're looking for here is mock objects (search for it at SO and Google in general, lots of info available) which help you decouple your class under test from other classes. Interestingly high amount of mocks in unit tests usually mean that your class could use some heavy refactoring.

(might be n00b question) will all the test cases be ran automatically? I do not want to go to the front end click bunch of stuff so that call to the DAO gets triggered.

All IDE:s allow you to run all the JUnit test at the same time, for example in Eclipse just click the source folder/top package and choose Run -> Junit test. Also when running individual class, all the unit tests contained within are run in proper JUnit flow (setup() -> testX() -> tearDown()).

when tests are ran will I find out which methods failed? and for the ones failed will it tell me the test method that failed?

Yes, part of Test Driven Development is the mantra Red-Green-Refactor which refers to the colored bar shown by IDE:s for unit tests. Basically if any of the tests in test suite fails, the bar is red, if all pass, it's green. Additionally for JUnit there's also blue for individual tests to show assertion errors.

lastly, any good starting points? any tutorials, articles that show working with Junit

I'm quite sure there's going to be multiple of these in the answers soon, just hang on :)

Esko
Thanks. after all the tests pass. I was planning to remove the methods with suffix '_old'. and will wait for resources. excited about finally getting to unit test :)
Omnipresent
+1  A: 

You'll write a test class.

public class OracleMatchesSqlServer extends TestCase {
    public void testHeadIdentifiersShouldBeEqual() throws Exception {
        String head = "whatever your head should be";
        IdentifierBean originalBean = YourClass.getHeadIdentifiers_old(head);
        IdentifierBean oracleBean = YourClass.getHeadIdentifiers(head);
        assertEquals(originalBean, oracleBean);
    }
}

You might find you need to parameterize this on head; that's straightforward.

Update: It looks like this:

public class OracleMatchesSqlServer extends TestCase {
    public void testHeadIdentifiersShouldBeEqual() throws Exception {
        compareIdentifiersWithHead("head1");
        compareIdentifiersWithHead("head2");
        compareIdentifiersWithHead("etc");
    }
    private static void compareIdentifiersWithHead(String head) {
        IdentifierBean originalBean = YourClass.getHeadIdentifiers_old(head);
        IdentifierBean oracleBean = YourClass.getHeadIdentifiers(head);
        assertEquals(originalBean, oracleBean);
    }
}
* Is this a good approach?

Sure.

* I will have multiple DAOs. Do I write the test methods inside the DAO
  itself or for each DAO I should have a separate JUnit Test Class?

Try it with a separate test class for each DAO; if that gets too tedious, try it the other way and see what you like best. It's probably more helpful to have the fine-grainedness of separate test classes, but your mileage may vary.

* (might be n00b question) will all the test cases be run automatically?
  I do not want to go to the front end click bunch of stuff so that call
  to the DAO gets triggered.

Depending on your environment, there will be ways to run all the tests automatically.

* when tests are ran will I find out which methods failed? 
  and for the ones failed will it tell me the test method that failed?

Yes and yes.

* lastly, any good starting points? any tutorials, articles that
  show working with Junit

I really like Dave Astels' book.

Carl Manaster
thanks. what do you mean by this - "You might find you need to parameterize this on head; that's straightforward."
Omnipresent
If you want to test for multiple values of the "head" variable, then you can pass it into a function... I'll update the answer to demonstrate.
Carl Manaster
A: 

Another useful introduction in writing and maintaining large unit test suites might be this book (which is partially available online):

XUnit Test Patterns, Refactoring Test Code by Gerard Meszaros

The book is organized in 3 major parts. Part I consists of a series of introductory narratives that describe some aspect of test automation using xUnit. Part II describes a number of "test smells" that are symptoms of problems with how we are automating our tests. Part III contains descriptions of the patterns.

mjustin