I can't put into my head how to design an app in order to perform unit tests. In particular when you have objects that depends on database queries, or other external factors (network/serial communication, etc...) Do you have any reading suggestion ?

Comments

  1. If you are talking to a database you should be able to mock the database connection. The code which then performs the query can be tested, and the results can be controlled through the mock and tested.

    You might have to write an extra layer which can be interfaced and mocked depending on the external factor you are dealing with. Sometimes this is a good idea as it abstracts you further from a specific implementation or vendor. But it adds what can appear to be extra code for no gain.

    ReplyDelete
  2. I know I'll get a shower of "Boo"s for this and I am aware it's not "by the book" and I understand my case may be peculiar :) but I just create a new datamodule, copy and paste the db components and use that :) I know it's probably not how it's supposed to work :) but still works for me :)

    ReplyDelete
  3. IMO, isolation is key.  If your code has layers where you can strip away dependencies, you increase the success rate.
    Test separately
      The inner core logic which process data elements
      The outer core logic which  process data sets
      The persistence logic which retrieve and store the data sets
      The process logic which handle retrieving, processing and storing data sets
      The event control logic which decides when or why you process data
     ... and so forth

    If you have GUI app, it helps immensely if your biz.logic is strictly decoupled from your UX - but - unfortunately this is very often not the case.  States are so often kept in visual controls, which makes it really hard to automate testing of the stuff that the UX is supposed to just be a thin, glossy layer above.

    ReplyDelete
  4. Mocking implies necessarily interface usage ? You must define  interface for each object to mock ?

    ReplyDelete
  5. Thank you Linas Naginionis  ! I began to read "head first design pattern", but as Nick Hodges  decided to do the Delphi translation work, I'll concentrate on your books ;)

    ReplyDelete
  6. In depends on what you want to test. If I need to test an object, which data and behavior depends on data in database, I run scripts putting the necessary data to the database in Setup method of TTestCase, test my object methods, and dispose data in Teardown method.

    ReplyDelete
  7. I will never be able to explain that to my colleagues who are sticked to Delphi 4 ... ;)

    ReplyDelete
  8. Since you asked for reading suggestions I'm going to recommend "Working Effectively with Legacy Code" by Michael Feathers. It is a treasure trove of advice on turning untestable code into testable code. Examples are in Java and C++ but are clear and to the point. Worth every penny.

    ReplyDelete

Post a Comment