0

I want to use a feature file with cucumber jvm that will hold the data for the test.

  • I am testing a method that uses hibernate to load an object before processing.

    public Deal getDealById(Long dealId) {
       deal = template.get(Deal.class, dealId);
       BigDecimal totalAmount = new BigDecimal();
       //loop through all of the loans related to this deal to add up a value
       for (Loan tempLoan: deal.loanList) {
           //add amount from each loan together
           BigDecimal totalAmount = totalAmount + tempLoan.amount;
       }
       //set the total amount value on the deal object
       deal.setTotalAmount(totalAmount);
       return deal;
    }
    

What do I do about the loading since I have to specify a dealId to load?

My understanding is that I need to "mock" the connection and the object resulting from the mocked connection.

I have looked at Jmock, mockito and dbunit respectively, but I don't understand what to do.

I would appreciate any input.

EDIT NOTES

I added more code, we are retrieving an object from the database. Next, we are looping through a list of objects related to the deal (many to one) and adding the amount of each loan to the deal amount. Finally, we set the total amount on the deal before returning the deal.

So how can I write a Junit test for this method considering I want to supply test information from a feature file?

In a "real" scenario this works, we load the deal in our application and add the loan amounts of each loan and set it onto the deal before returning it. But I don't understand how to write a JUnit for this test considering we have to load from the database inside this method.

Adam
  • 95
  • 1
  • 2
  • 8
  • Whats the logic-containing code you need to test? – Garrett Hall Aug 07 '12 at 18:47
  • I added more code for the method I want to test. Maybe I still don't get what exactly I'm suppose to be testing, we have a test case that states all the loan amounts must be summed together on the deal object. So for the test case to pass....I need to have a deal object with a list of loan objects and add each loan amount together before adding it to the deal for the test case to pass. Does that make sense to anyone? – Adam Aug 07 '12 at 19:15

2 Answers2

1

Refactor the logic into your Deal class and you shouldn't need to mock a database at all. Plus it's better OO design.

public Deal getDealById(Long dealId) {
   return template.get(Deal.class, dealId);
}

public class Deal {
   public BigDecimal recalculateTotalLoanAmount() {
      BigDecimal totalAmount = new BigDecimal();
      for (Loan tempLoan: deal.loanList)
         totalAmount = totalAmount + tempLoan.amount;
      setTotalAmount(totalAmount);
      return totalAmount;
   }
}
Garrett Hall
  • 29,524
  • 10
  • 61
  • 76
  • Okay I do agree with the re-factoring, but I still don't get how to write a JUnit for my test case. I guess I will accept this answer and do more research before posting another question. – Adam Aug 07 '12 at 19:33
  • Create a `Deal` with `Loans` and then just call the method with an `assertEquals` – Garrett Hall Aug 07 '12 at 20:44
  • @Adam - You shouldn't accept the answer if you feel that it doesn't answer the original question. This will make it less likely that other people will come along and provide answers. It also creates a problem for other people who have the same question that you do. – Dawood ibn Kareem Aug 07 '12 at 23:53
  • My original question was unclear. Anyway, for anyone looking at this in the future, re-factor your code to separate your DAO layer (or database loads) from the rest of your code...it's not an option for me unfortunately. From my research, I need to mock a database....but finding an actual good example has been problematic. Some of the "examples" of the mock database have basically just created another schema and set of tables....that's not a mock...that's just another set of "test tables". But that's a different issue...how do I actually mock a database...like how we can mock objects? – Adam Aug 08 '12 at 19:55
  • Use dependency injection, either through a framework such as Guice or by exposing setters in your database service. If you really can't mess with the legacy code try PowerMock. – Garrett Hall Aug 08 '12 at 20:40
0

I agree with the Garrett's answer that you should refactor your code. However, you have stated in your comments that refactoring "it's not an option for me". With this in mind an alternative solution is to use a database rather than trying to mock one.

There are a number of embedded in-memory databases that can be used as part of your unit tests (e.g. HSQLDB, H2, Apache Derby). You define your database schema in a file so the database is created on the fly. You can also pre-load your database tables with test data so your tests dont have to create it. In-memory database are very fast to load.

I would strongly recommend that you use a Java a framework like Spring which has convenient configuration for getting this type of setup running for you in just a few lines of XML. But, considering you can't refactor your code this probably isn't an option.

Brad
  • 15,186
  • 11
  • 60
  • 74
  • Hi, Brad. Do you have any experience using an in-memory DB shared between cucumber and the application under test? Meaning the application and cucumber tests will be able to write and read info from the DB, and, of course, one must be able to see the data from the other. I've tried that and I faced an issue: it seems cucumber tests and the application are running on separate JVM so they load a different in-memory DB. That's a problem. FWIW, cucumber tests and the application are ran using two maven plugins: spring-boot and failsafe. Probably that's the reason. Do U have any insights on this? – jbuddy Aug 26 '20 at 06:03