I'm trying to run a unit test on a method that sends an email in Microsoft Visual Studio using c#. I am working as an intern and was given a project to create a contactUs page and that works fine. But now my unit tests keeping giving me errors. This is my
ContactUsEmailServiceTest.cs code:
using System.Configuration;
using Coop.BusinessLayer.Interfaces.Common;
using Coop.BusinessLayer.Services;
using Coop.BusinessLayer.Services.Dto.Input;
using Moq;
using NUnit.Framework;
namespace Coop.Services.Tests
{
[TestFixture]
public class ContactUsEmailServiceTests
{
private Mock<IEmailService> _emailService;
private Mock<IResourcesAccessService> _resourcesAccessService;
private Mock<ILogger> _logger;
private ContactUsEmailService _sut;
[SetUp]
public void PerTestSetup()
{
_emailService = new Mock<IEmailService>();
_resourcesAccessService = new Mock<IResourcesAccessService>();
_logger = new Mock<ILogger>();
_sut = new ContactUsEmailService(_emailService.Object, _resourcesAccessService.Object, _logger.Object);
}
[Test] //NS Receiver is not set in web config file
public void SendEmail_WhenNSReceiverIsNull_EmailIsNotSent()
{
//do stuff...
}
[Test] //NS Receiver is set in web config file as empty string
public void SendEmail_WhenNSReceiverIsEmpty_EmailIsNotSent()
{
//do stuff...
}
[Test]
public void SendEmail_WhenEmailTemplateIsEmpty_EmailIsNotSent()
{
//do stuff...
}
[Test]
public void SendEmail_WhenEmailIsSend_EmailBodyIsProperlyFormated()
{
//do stuff...
}
[Test]
public void SendEmail_WhenEmailIsSentAndNameIsNotAvailable_TheNameIsFilledWithDefaultValueInEmailBody()
{
//arrange
ConfigurationManager.AppSettings["northern-safety-contact"] = "contact";
_resourcesAccessService.Setup(r => r.GetResourceValue("EmailTemplate")).Returns(GetEmailTemplate());
// Todo: Change input, set Contact Name to string.Empty
var ContactUsDto = GetContact();
ContactUsDto.Name = string.Empty;
// Todo: Update the expect result, replacing Name with "Not Available"
// See GetContactDetail() as part of ContactUsEmailServices
var emailBody = GetEmailBody(ContactUsDto);
//act
_sut.SendEmail(ContactUsDto);
//assert
//check if email was sent
/****EXCEPTION REQUIRED HERE - THIS IS WHERE MY DEBUG FAILS******/
_emailService.Verify(e => e.SendMail(ContactUsDto.Email, ContactUsDto.Email, "User feedback", emailBody));
}
private static ContactUsDto GetContact()
{
var contactUsDto = new ContactUsDto()
{
//Todo: Create Map to Dto
Name = "Name",
Email = "123@example.com",
PhoneNumber = "0123456789",
Street = "Street",
City = "City",
State = "State",
PostCode = "PostCode",
Comments = "Comments",
};
return contactUsDto;
}
private static string GetEmailBody(ContactUsDto ContactUsDto)
{
// ToDo: Set expected body
string emailTemplate = GetEmailTemplate();
string emailBody;
// ToDo: Create Email Body by formatting the emailTemplate
emailBody = System.String.Format(emailTemplate, ContactUsDto.Name, ContactUsDto.Email, ContactUsDto.PhoneNumber, ContactUsDto.Street,
ContactUsDto.City, ContactUsDto.State, ContactUsDto.PostCode, ContactUsDto.Comments);
return emailBody;
}
private static string GetEmailTemplate()
{
// Todo: Define Template
return
@"Name<br />Email<br />PhoneNumber<br />Street<br />City<br />State<br />PostCode<br />Comments<br />";
}
}
}
And this is the ContactUsEmailService.cs code I'm trying to test.
using System;
using System.Configuration;
using Coop.BusinessLayer.Interfaces.Common;
using Coop.BusinessLayer.Services.Dto.Input;
namespace Coop.BusinessLayer.Services
{
public class ContactUsEmailService : IContactUsEmailService
{
private readonly IEmailService _emailService;
private readonly IResourcesAccessService _resourcesAccessService;
private readonly ILogger _logger;
private const string NotAvailable = "Not Available";
public ContactUsEmailService(IEmailService emailService, IResourcesAccessService resourcesAccessService, ILogger logger)
{
_emailService = emailService;
_resourcesAccessService = resourcesAccessService;
_logger = logger;
}
public bool SendEmail(ContactUsDto contactUsDto)
{
var receiver = ConfigurationManager.AppSettings["northern-safety-contact"];
if (string.IsNullOrEmpty(receiver))
return false;
contactUsDto.Name = GetContactDetail(contactUsDto.Name);
var emailBody = GetEmailBodyFormated(contactUsDto);
if (string.IsNullOrEmpty(emailBody))
return false;
try
{
// ToDo: Set Sender Email address
_emailService.SendMail(contactUsDto.Email, receiver,
ServiceResources.EmailTitle, emailBody);
}
catch (Exception ex)
{
_logger.LogError(ex);
return false;
}
return true;
}
private string GetEmailBodyFormated(ContactUsDto contactUsDto)
{
string emailTemplate = _resourcesAccessService.GetResourceValue("EmailTemplate");
string emailBody = null;
if (string.IsNullOrEmpty(emailTemplate))
return string.Empty;
// ToDo: Create Email Body by formatting the emailTemplate
if (emailTemplate != null)
emailBody = String.Format(emailTemplate, contactUsDto.Name, contactUsDto.Email, contactUsDto.PhoneNumber, contactUsDto.Street,
contactUsDto.City, contactUsDto.State, contactUsDto.PostCode, contactUsDto.Comments);
return emailBody;
}
private static string GetContactDetail(string contactInfo)
{
return string.IsNullOrEmpty(contactInfo) ? NotAvailable : contactInfo;
}
}
}
I really don't know too much about Unit testing. I started this internship like 3 weeks ago and kind of go thrown into the idea of using controllers, models and views, I have never really used them before. But now I understand them very well, at leats I think I do. Anyway, I cant seem to get my Unit test to pass, it keeps failing on the line
_emailService.Verify(e => e.SendMail(ContactUsDto.Email, ContactUsDto.Email, "User feedback", emailBody));
When I try to debug the test a box pops up saying MockException was unhandled by user code. if I gopy exception details to clipboard this is what I get:
Moq.MockException was unhandled by user code HResult=-2146233088 Message= Expected invocation on the mock at least once, but was never performed: e => e.SendMail(.ContactUsDto.Email, .ContactUsDto.Email, "User feedback", .emailBody) No setups configured. Performed invocations: IEmailService.SendMail("123@example.com", "contact", "Northern Safety co., inc. Automatic Response", "Name
PhoneNumber
Street
City
State
PostCode
Comments
") Source=Moq IsVerificationError=true StackTrace: at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable1 setups, IEnumerable1 actualCalls, Expression expression, Times times, Int32 callCount) at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times) at Moq.Mock.Verify[T](Mock1 mock, Expression1 expression, Times times, String failMessage) at Moq.Mock1.Verify(Expression1 expression) at Coop.Services.Tests.ContactUsEmailServiceTests.SendEmail_WhenEmailIsSentAndNameIsNotAvailable_TheNameIsFilledWithDefaultValueInEmailBody() in c:\TFS\AppDev\Co-Op Training\Dev-Jordan\Src\Coop.Services.Tests\ContactUsEmailServiceTests.cs:line 75 InnerException:
Let me know if you need anything else. Thank you!!!!
Aucun commentaire:
Enregistrer un commentaire