views:

61

answers:

6

How do I accomplish this? The SMTP class throws error on dev machine about not finding an SMTP server. Is there a way to test sending emails on development machine?

A: 

I usually do this by creating a wrapper class for the SmtpClient, then mocking out the wrapper in my tests. This removes the actual mail client/server dependencies from my unit tests. The wrapper itself is relatively thin so I don't feel the need to create tests for it. Usually I do my integration level testing for things like this as exploratory tests in my staging environment. The staging environment typically uses a production mail server, but with "fake" data -- e.g., customer email addresses replaced with my own.

Having said that, I would expect the client to work without errors even on your development system unless your mail server is protected by a firewall or something that would prevent your dev system talking to it. Can you give more detail on what the error you are experiencing?

tvanfosson
I think the other answers offer a much simpler solution that are more tailored to the question, that about "sending test emails" rather than "test sending emails".
awrigley
@awrigley - for automated tests, handling both success and error conditions, mocking is definitely easier than using the real class. I feel comfortable using mocks to ensure my code is using the class properly and doing exploratory testing to make sure that the integration is done properly. If you have tests where you need to ensure that the mails are properly formatted, the links in them work, etc. then using some sort of store and forward mechanism that allows you hand inspect them may be needed. Note: mocking doesn't preclude the other types of testing.
tvanfosson
tvanfosson, I don't doubt the validity, or the quality, of what you say. But... it isn't an answer to the question. Again, the question is about sending test emails, not testing the sending of the emails. As such it is confusing to someone who needs this question answered.
awrigley
@awrigley - I see your point **and** that may be what the OP meant, but that is not what the OP actually asked. As such anyone else arriving here is likely going to be confused by the accepted answer, not mine. I quote "how to test sending emails from asp.net..." is most decidedly not "how can I test why I can't send email from my machine."
tvanfosson
@tvanfosson: I don't agree, but so be it. The reason he can't send emails from his machine is that he isn't using IIS. If he doesn't know that, the intricacies of integration testing is above his skill set right now. I remember my sense of enlightenment (and relief) when I found the <specifiedPickupDirectory /> setting and there is little doubt in my mind that that is the answer he needs. He SHOULD know about integration tests, but he doesn't, not right now at least. We've all got to learn to walk before running. But hey, we agree to differ.
awrigley
+4  A: 

You can dump the files on disk, by configuring System.Net.Mail.SmtpClient to use a deliveryMethod of type SpecifiedPickupDirectory, I found an example on SO

Marijn
When writing unit tests for classes that use SmtpClient, I run an in-process smtp server with my unit tests. I used [netDumpster](http://netdumbster.codeplex.com/) for this purpose.
Marijn
Do I have to install a smtp client or something?
Shawn Mclean
No you don't, you can run it from within your unit tests.
Marijn
netDumpster has some documentation on how to do this.
Marijn
Strictly speaking this wouldn't be **unit** testing since you're not isolating the code under test from its dependencies. I'd consider it more of an "isolated" integration test where the part you're stubbing isn't the framework code, but the external dependency that the framework uses. You gain a little simplification at the expense of some additional coupling -- that's not necessarily bad, but you should be aware of the architectural implications of testing this way. What would you do if you wanted to support notification by IM **and** email in the future?
tvanfosson
I agree, strictly speaking it is a simple integration test, ran using a unit testing framework.
Marijn
A: 

Without seeing the exception there's not much we can do. As long as the details on your dev machine are pointing to a proper smtp server and have the correct credentials then your code won't be the issue and you should look further down the chain. I had an exception of the target machine refusing the request despite everything else being right. After spending ages double and triple checking the credentials, sending from our server etc I tracked the bug down to McAfee blocking email port 25...

Chao
+2  A: 

There's a couple possible reasons for this.
1) Is your code configured to use local SMTP server during development and you've upgraded to windows 7? There's no longer a SMTP server available on your localhost. Find and download smtp4dev to allow your localhost to trap the sent Emails.
2) If you are using a remote SMTP server, check your windows firewall to confirm that you are allowed to send outgoing mail. If you are, then confirm that your machine/username has rights to send mail via that server. A quick telnet:25 to the server should let you know if your connection is refused or not.

ARM
#1 is my solution. Thanks.
Shawn Mclean
+3  A: 

Shawn,

Straight from my web.config:

  <smtp deliveryMethod="SpecifiedPickupDirectory">
    <network host="ignored" />
    <specifiedPickupDirectory pickupDirectoryLocation="c:\email_c#" />
  </smtp>

this works fine insofar as being able to review the 'emails' that get saved into the pickupDirectoryLocation directory.

Give it a try...

jim
thank you......
Shawn Mclean
pleasure.......
jim
A: 

Assuming by "test sending emails" you mean sending test emails instead of formal/unit testing, I like to use smtp4dev: http://smtp4dev.codeplex.com/

As the page explains, it's a dummy SMTP server, basically intercepting your outgoing messages from your app, allowing you to examine those messages and make sure everything works as you expect. It's a Windows app, which hopefully isn't an issue if you're developing for ASP.NET.

Yohan P