TDD approach for complex function

I have a method in the class for which they represent several different results (based on responses to events, etc.). But this is the only atomic function that is used by other applications.

I have broken down the basic blocks of functionality that include this function in different functions, and have successfully applied a testing approach to the functionality of each of these elements. However, these elements will not be used for other applications.

And so my question is, how can / easily approach the TDD style solution to verify that the only method that needs to be called works correctly without a lot of duplication in testing or the many settings needed for each test?

I examined / looked at moving blocks of functionality to another class and used Mocking to simulate the answers of the functions used, but it doesn’t feel good and individual methods should write variables in the main class (it really felt like heins robinson).

The code roughly looks like this (I removed a lot of parameters to make everything clearer, as well as a fair bit of irrelevant code).

public void MethodToTest(string parameter) { IResponse x = null; if (function1(parameter)) { if (!function2(parameter,out x)) { function3(parameter, out x); } } // ... // more bits of code here // ... if (x != null) { x.Success(); } } 
+4
source share
4 answers

I think that you would make your life easier by avoiding the out keyword and rewriting the code so that the functions either check some condition for the answer or change the answer, but not both. Sort of:

 public void MethodToTest(string parameter) { IResponse x = null; if (function1(parameter)) { if (!function2Check(parameter, x)) { x = function2Transform(parameter, x); x = function3(parameter, x); } } // ... // more bits of code here // ... if (x != null) { x.Success(); } } 

That way, you can start understanding and recombining parts of your large method more easily, and in the end you should have something like:

 public void MethodToTest(string parameter) { IResponse x = ResponseBuilder.BuildResponse(parameter); if (x != null) { x.Success(); } } 

... where BuildResponse is where all your current tests will be, and the test for MethodToTest will now be pretty easy to mock ResponseBuilder.

+1
source

IMHO, you have a couple of options:

  • Divide the internal functions into another class so you can mock them and make sure they are called. (what you already mentioned)
  • It seems that the other methods you created are private methods and that this is the only public interface in these methods. If so, you should run these test cases using this function and check the results (you said that these private methods modify class variables) instead of checking private methods. If this is too painful, I would consider redesigning your design.

It seems to me that this class is trying to do something more. For example, the first function does not return an answer, but the other two. In your description, you said that the function is complex and requires many parameters. These are both signs that you need to reorganize your design.

0
source

Your best option will really be to mock functions 1,2,3, etc. If you cannot move your functions to a separate class, you can study the use of nested classes to move functions, they will be able to access data in an external class. After that, you should be able to use mocks instead of nested classes for testing purposes.

Update: looking at your sample code, I think that you can get inspiration by looking at the visitor’s template and how to test it, this may be appropriate.

0
source

In this case, I think you are simply making fun of method calls, as you mentioned.

Usually you write your test first, and then write the method so that all tests pass. I noticed that when you do it this way, the written code is very clean and close to the point. In addition, each class is very good only in that it has only one responsibility, which can be easily tested.

I don’t know what’s wrong, but something doesn’t smell right, and I think there may be a more elegant way to do what you do.

0
source

Source: https://habr.com/ru/post/1308926/


All Articles