Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write code which is hard to unit test

In an interview, I was asked the question “How do you make a code hard to be unit tested?” I ended up mumbling something about writing a tightly coupled code. Can anyone please tell me what’s the right answer/ approach for this question?

like image 340
Faux Pas Avatar asked Apr 10 '13 05:04

Faux Pas


4 Answers

Take a look at Mishko's Guide: Writing Testable Code, introduce as many of these flaws into your code and you'll end up with untestable code.

For example:

  • do as much as you can in constructors, start threads, use loops and ifs
  • break Law of Demeter by creating long chain of method calls
  • use singletons everywhere, never ask for dependencies, look them up in a static provider
  • create god classes with 2k lines of code
like image 108
denis.solonenko Avatar answered Oct 22 '22 07:10

denis.solonenko


Well some answers could be

  • a Code which accesses the database
  • a Code which behaves according to the system datetime
  • a Code which does more than one functionality in the same methode (Unit)
  • a Code with a lot of coditional behaviour which depends on another unreadbale code

and in genral any code where it is hard / impossible to simulate the environment in order to let it behave the way which needs to be tested.

like image 45
CloudyMarble Avatar answered Oct 22 '22 09:10

CloudyMarble


That is a good answer. Tightly coupled code is extremely hard to unit test (and probably shouldn't be unit tested - it should be re-factored first), because by definition unit tests can only test a specific unit of something. All calls to databases or other components of the system should be avoided from Unit Tests because they violate this.

With that said you could also mention that Integration Tests are good for testing larger couplings of code or code with dependencies, or even behavior based actions. You can build an integration test suite for something like testing your REST API which has many dependencies and even crosses many technologies and multiple programming languages.

Also by not thinking through a design or not using a decent design pattern can lead to extremely coupled or dependent code which can be difficult or impossible to unit test without re-factoring or re-writing. You could then talk about TDD (Test Driven Development http://en.wikipedia.org/wiki/Test-driven_development) or BDD (Behavioral Driven Development http://en.wikipedia.org/wiki/Behavior-driven_development) which forces you to start by designing the test suite and working from there.

like image 1
Lucas Avatar answered Oct 22 '22 09:10

Lucas


  • Creating dependencies required by a class using new operator yourself will be enough! This means tightly coupled code which is your answer.
  • A code that does not follow SOLID principles.

So in the test you will not be able to use Mock objects as you are creating the dependencies yourself and hardcoding the relationships.

With dependency injection you are able to use polymorphic behavior so the class which is calling some method on the dependency passed to it in constructor or method does not need to know the concrete type. So in testing you can pass a mock object and you will be able to test your class easily.

Misko's Writing testable code explains how we are good at writing code that is not testable and how to solve it.

Example (JAVA):

//hard to unit test this code as testing class A also requires that ClassB should work properly
//What is ClassB does some I/O or DB operations. This makes unit test a integration test
class classA{
   ClassB b = new ClassB();   //Creating concrete dependencies

}

interface B{
     //implemented by Class B and your mock class that you create for testing
}

class ClassA{
     private B b;

     //Here you can use mocking framework or create a mock class yourself and pass that as argument
     //So the mock class will not do any DB or I/O and makes this unit test
     public classA(B b){
         this.b = b;
     }
}
like image 1
Narendra Pathai Avatar answered Oct 22 '22 08:10

Narendra Pathai