1

I've built a console line application for importing CSV data, validating against a set of constraints and then adding it into a database if it passes all validation. As such, I've developed a few classes for common classes such as:-

  • Test data is not too long
  • Test data matches RegEx
  • Test data exists

These all have their own try-catch blocks, and in the try-catch block, I've set it to send an email to a generic inbox with the Exception. This is a requirement for when it goes live, so we are aware if something does fail.

I've written unit tests to call those functions and have deliberately called these functions with a view to break them to see how the application performs and the results of these tests. But of course, when it breaks it hits the Exception and then sends me this email. This is killing my tests, each test has gone from <1ms to 10-15secs and we're getting this spam everytime we test. Yet we need to keep these tests for when the project is live.

Is there some way to specify that tests wont send emails or will the #debug command work here?

Thanks, Mike.

Mike Upjohn
  • 1,251
  • 2
  • 16
  • 38
  • Wrapping every method within a try catch will have performance issues if your code keeps throwing exceptions. Please see this, http://stackoverflow.com/questions/32394582/wrap-every-method-in-try-catch-or-specific-part-of-code – Harry Oct 05 '15 at 09:05
  • 2
    @Harry in this case, Mike is doing something meaningful, so *should* `catch`. The performance of the catch without an exception is less of an overhead than you might think (see also: http://stackoverflow.com/q/1308432/50447) – Rowland Shaw Oct 05 '15 at 09:11
  • @RowlandShaw thanks for the link, thats interesting! – Harry Oct 05 '15 at 09:28

1 Answers1

4

The correct answer is to abstract out your email sending into an interface that can be injected into your class via the constructor. Then you can mock that interface using a framework like Moq for your unit tests, allowing you to verify that the call to IEmailer.Send occurred, without actually having to send those emails out.

Callum Bradbury
  • 936
  • 7
  • 14
  • Thank you for this, I'm going to go and research and let you know how it turns out. – Mike Upjohn Oct 05 '15 at 09:29
  • No problem, if you're feeling adventurous look up the SOLID principles, they'll revolutionize your development and aren't really that difficult to put into practice. – Callum Bradbury Oct 05 '15 at 09:33
  • Of course, it would also be worth separating the tests so that some tests check that you get the correct exception(s) for the different types of malformed input, and another test checks that the correct types of exception are reported/logged/handled via a mocking/injection approach – Rowland Shaw Oct 05 '15 at 09:38
  • Really he wants to be mocking out the various validation classes as well. They should have their own unit tests for checking that they throw exception X, Y and Z in given situations. For testing his main class he should be mocking the validation classes and using something like Moq to simulate exceptions, then verifying that the reporter classes are triggered. Essentially the rule for unit testing is mock everything, always. It's probably worth having integration tests that actually verify emails are sent etc but they only need to test the IEmailSender implementation, nothing else. – Callum Bradbury Oct 05 '15 at 09:46
  • Thanks guys! Will report back. – Mike Upjohn Oct 05 '15 at 10:19