DEV Community

Discussion on: When TDD doesn't click, something else should click "harder"!

Collapse
 
richremer profile image
Rich Remer

I don't mean to be a dick, but if you're making HTTP requests in your tests, you're almost certainly doing something wrong. Try dependency injection. If you use the new keyword inside a function, you make that function untestable.

Once you learn how properly test and refactor an existing codebase, then you might have the experience necessary for TDD.

Collapse
 
yaser profile image
Yaser Al-Najjar • Edited

I don't mean to be a dick

Not a problem as long as you're right 😉

So I will throw in my 0.2 cents about DI, mocks, and fakes. I will start by saying they are all great tools but if they are written against YOUR OWN code.

Lemme mention a simpler example, when you do frontend dev and you need some API, do you WRITE YOUR OWN mock server from scratch, or USE an already built mock server (like postman), make the necessary endpoints and responses, and plug it into your code (replace the url)?

I believe it's not your job to mock the world, your job is to mock the services you create, not other people's services.

WHY?

Because the moment you start doing this: stackoverflow.com/a/36425948/4565520

It means you're testing what the mock is supposed to do, and NOT what the what the service as a whole is supposed to do... you're basically cheating yourself with a passing test for that mock code that's guaranteed to work.

So, to keep your tests more "honest", and not cheating yourself, the person who wrote that service (say HTTPClient) is supposed to write its mock as well so that you don't WRITE your own mock, but you USE an already built mock.

Actually, if you find yourself mocking AuthService or HTTPClient that are supposed to be PART OF THE FRAMEWORK you use, then I guess it's time to start questioning your framework!

Some mature frameworks like django provides you with the necessary tools to make your tests easy as breeze, like calling your controllers without going through the hustle of DI and RepositoryPattern and preparing a db to run your tests on... bla bla bla!

  • I'm not comparing frameworks here... I'm just pointing out to use the right framework for the right purpose.

Of course you can create mocks for each and every service you face, but aside from the fact "it's not my business"... I don't have the luxury of time to do that, and I'm sure you don't as well.


Ah... btw, this controller mentioned above has this constructor full of injected services, but it does NOT solve the problem I'm mentioning from the very beginning, so my point about "you end up testing the framework" still holds.

public StudentController(IEntryAgentRepository repository, 
IAgentStudentService agentStudentService, 
IAnonymousApplicationTracker anonymousApplicationTracker,
UserManager<Agent> userManager,
SignInManager<Agent> signInManager,
IAuthorizationService authorizationService, 
IHostingEnvironment environment)
{
    _repository = repository;
    _agentStudentService = agentStudentService;
    _userManager = userManager;
    _authorizationService = authorizationService;
    _environment = environment;
    _anonymousApplicationTracker = anonymousApplicationTracker;
    _signInManager = signInManager;
}