DEV Community

Discussion on: You are mocking it wrong.

Collapse
 
idanarye profile image
Idan Arye

You don't want to make HTTP calls while running your unit tests suite, you don't want to send out emails, neither do I.

Why wouldn't you though? I mean, obviously you wouldn't want to make HTTP calls to a production server and you wouldn't want to send emails to the actual clients - but what's wrong with sending mails to some testing account or to your own dummy mail server like FakeSMTP, and verifying that you receive these mails?

Collapse
 
belinde profile image
Franco Traversaro

Do you REALLY have written a unit test that send mail and assertPopServerHasMail()? :-/

Collapse
 
asizikov profile image
Anton Sizikov

I actually have a set of end-to-end tests where we send emails and verify their content. There is a problem - emails go through the MailChimp and on test environment it may take quite some time.

Anyway, that's not the point of the article :) I see the value in sending the email out as well I see the value in a quick test run. We have to be practical and try to find the balance.

Mocking out the MailChimp client/queue manager/database/http call/ domain boundary is something we have to do if we want to run tests often, and be able to execute the test suite offline (I work on a plane sometimes :) ). I just want people to stop overusing mocks.

Collapse
 
idanarye profile image
Idan Arye

I agree - my philosophy is that when you need to mock you should consider making it an integration test.

My point is that even when you absolutely can't do the same thing the actual production program will do(e.g. - sending emails), you don't always have to do a traditional mock objects. Maybe going through an actual mail service makes the cycle too long, but if you set up your own local "mail service"(with FakeSMTP or something similar) you can send and verify the emails quickly enough, and it should be much easier to do than to use a mock email client - and also be a better test since it tests against a real API.

Another example - instead of mocking your model classes, set up a small database server. If your ORM is opaque enough you may even use an in-process database like SQLite or H2. It should have orders of magnitude less entries than a real production database(or even a testing database!) so it should run fast enough and fit within the memory limits of whatever machine you use for testing.

Thread Thread
 
asizikov profile image
Anton Sizikov

When SQLite db is a great choice for in-memory test database (I have about 7k tests like that in my current project, love it so much, but that's a different story), replacing the mail service is not always a good solution. When you test your code against the service which is very different from the one you use in production, what do you really test?

That's the same trade-off: do we verify an integration with the test service, or with the mock? If the test service is close enough to the system you have in prod, it is fast enough, then I would say go for it.