Testing

21 Aug 2022

(WIP) Testing

This is an article to help me to organize my thoughts around Unit Test, Integration Test, Acceptance Test and TDD/BDD, and what I should do to adjust my currently approach if I am wrong on my approach.

The approach I should take should answer these questions:

  1. How can I refactor and do not change Tests(Unit Test or whatever)?
  2. How can I cover the user scenario instead of a code scenario and is that the right application?

What is the approach I am currently taking?

The approach that I am currently taking is to add Test into a Controller when it is possible, since the controller is the endpoint/facade for the customer and that behavior is hardly to change. I avoid to test anything that I do not have control such as Databases, Callout and external Libraries.

In case of Salesforce, I would mock only the Salesforce Callout and Selector/DAO classes. Now everything else that I have the control, in other words, all the classes that I created, I would not mock and execute the Test.

In case of .Net Project, I would mock only Wrapper and Repository classes. A wrapper would be in case I am using a dll/library, example is a library to generate the PDF, I don’t need to Test that, so I have a wrapper around that and I would mock the result of that.

What are the pros of using this approach?

  1. I would add a Test Scenario in a class which would really validate if the response that the customer is waiting is correct. Since the customer would always execute the Controller and not the internal classes.
  2. If I refactor any internal implementation, by splitting classes or rename methods, I would not need to change any of the Tests.

What are the cons of using this approach?

  1. In some cases, the amount of things you have to “Arrange/Setup” the test would be big, because you have to Mock all the dependencies of that class.
  2. It would be hard to find a bug if you have multiple classes being executed in the controller and you don’t have “unit test” for those classes because you are testing many other classes.
  3. Because those test are “complex”, it is hard to implement all the scenarios. When I mean by that, is that internal classes could have methods which could have a N scenarios, and for you to test each scenario you would need to create a Test Scenario for the Controller to execute that N scenario the method. If you have a Unit Test to test that method specific, that would be an easy setup and you would cover all the scenarios.

What is a Callout class? Callout class is a class that we use to do a REST Endpoint to another System.

What is an internal Implementation? My view, internal implementation is any class that helps the facade class to do its job. Example, if I have a HouseBuilder class(facade), and I have TwoStorageHouse class, OneStorageHose Class, and HouseBuilder instantiate those two classes, for me this would be a internal implementation. I think the secret to define if it is internal implementation is when we instantiate or when we inject those classes. When we instantiate a class inside of another class, that class would be an internal class implementation. When we inject a class, that class would be a class that we should mock. This should happens only for classes that we do not control, like Wrapper classes, Database classes(Repository/Selector/DAO) and Callout Classes.