I have the following controller action
public void Post(Dto model)
{
using (var message = new MailMessage())
{
var link = Url.Link("ConfirmAccount", new { model.Id });
message.To.Add(model.ToAddress);
message.IsBodyHtml = true;
message.Body = string.Format(@"<p>Click <a href=""{0}"">here</a> to complete your registration.<p><p>You may also copy and paste this link into your browser.</p><p>{0}</p>", link);
MailClient.Send(message);
}
}
To test this I need to setup the controller context
var httpConfiguration = new HttpConfiguration(new HttpRouteCollection { { "ConfirmAccount", new HttpRoute() } });
var httpRouteData = new HttpRouteData(httpConfiguration.Routes.First());
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost");
sut = new TheController
{
ControllerContext = new HttpControllerContext(httpConfiguration, httpRouteData, httpRequestMessage),
MailClient = new SmtpClient { PickupDirectoryLocation = location }
};
This seems like a lot of setup to test the creation of a link. Is there a cleaner way to do this? I have read about in-memory servers but that looks like it applies more to the httpclient than testing the controller directly.
I started using this approach with Web API 2.0.
If you're using a mocking library (and you really should for any real world unit tests), you are able to directly mock the UrlHelper
object as all of the methods on it are virtual
.
var mock = new Mock<UrlHelper>();
mock.Setup(m => m.Link(It.IsAny<string>(), It.IsAny<object>())).Returns("test url");
var controller = new FooController {
Url = mock.Object
};
This is a far cleaner solution than Ben Foster's answer, as with that approach, you need to add routes to the config for every name that you're using. That could easily change or be a ridiculously large number of routes to set up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With