I am trying to implement unit testing for a surface controller. The GET method tries to read some properties of the CurrentPage and POST method tries to redirect to the ChildPage of the CurrentPage. The problem I am encountering is I can never get the UmbracoContext in my unit tests. Has someone encountered and solved this? Any help much appreciated
This is an example of what my code will do on POST
public ActionResult PostRegistrationForm(ChosenRegistrationViewModel model, HttpPostedFileBase photo)
{
//do some logic and if successful redirect
var thankYouPage = CurrentPage.ChildrenOfType(ChosenThankYouPage.ModelTypeAlias).FirstOrDefault();
return this.RedirectToUmbracoPage(thankYouPage, "eventId=" + model.SignUpEventId.ToString() + "®istrationId=" + model.Id.ToString());
}
public class TestingTests : UmbracoBaseTest
{
private readonly UmbracoHelper umbracoHelper;
private readonly Mock<IPublishedContent> currentPage;
private readonly RegistrationController controller;
public TestingTests()
{
base.SetUp();
this.currentPage = new Mock<IPublishedContent>();
this.umbracoHelper = new UmbracoHelper(this.currentPage.Object, Mock.Of<ITagQuery>(), this.CultureDictionaryFactory.Object, Mock.Of<IUmbracoComponentRenderer>(), this.PublishedContentQuery.Object, this.MembershipHelperImplementation);
this.controller = new RegistrationController(Mock.Of<IUmbracoContextAccessor>(), Mock.Of<IUmbracoDatabaseFactory>(), base.ServiceContext, AppCaches.NoCache, Mock.Of<ILogger>(), Mock.Of<IProfilingLogger>(), umbracoHelper);
}
[Fact]
public void Given_SuccessfullRegistration_When_PostRegistrationForm_Then_RedirectToThankYouPageWithExpectedQueryString()
{
var thankYouPageType = new Mock<IPublishedContentType>();
thankYouPageType.Setup(x => x.Alias).Returns("thankYouPage");
var thankYouPage = new Mock<IPublishedContent>();
thankYouPage.Setup(x => x.Id).Returns(123);
thankYouPage.Setup(x => x.Url).Returns("/thankyou");
thankYouPage.Setup(x => x.ContentType).Returns(thankYouPageType.Object);
this.currentPage.Setup(x => x.ChildrenForAllCultures).Returns(new List<IPublishedContent>() { thankYouPage.Object });
var registrationModel = new ChosenRegistrationViewModel()
{
Id = 456,
SignUpEventId = 789
};
var result = (RedirectResult)this.controller.PostRegistrationForm(registrationModel);
result.Url.ShouldBe("/thankyou?eventId=789®istrationId=456");
}
}
public class RegistrationController : SurfaceController
{
private readonly UmbracoHelper umbracoHelper;
public RegistrationController(IUmbracoContextAccessor umbracoContextAccessor,
IUmbracoDatabaseFactory umbracoDatabaseFactory, ServiceContext serviceContext, AppCaches appCaches,
ILogger logger, IProfilingLogger profilingLogger, UmbracoHelper umbracoHelper) : base(
umbracoContextAccessor, umbracoDatabaseFactory, serviceContext, appCaches, logger, profilingLogger,
umbracoHelper)
{
this.umbracoHelper = umbracoHelper;
}
[HttpPost]
public ActionResult PostRegistrationForm(ChosenRegistrationViewModel model)
{
//do some logic and if successful redirect
var thankYouPage = this.umbracoHelper.AssignedContentItem.ChildrenOfType("thankYouPage").FirstOrDefault();
return Redirect(string.Format($"{thankYouPage?.Url}?eventId={model.SignUpEventId}®istrationId={model.Id}"));
}
}
public class ChosenRegistrationViewModel
{
public int Id { get; set; }
public int SignUpEventId { get; set; }
}
I ended up ditching RedirectToUmbracoPageResult because it turned out to be quite hard to Assert (queryStringValues is a private field, Url fields uses static resolver Current to resolve current page instead of DI), instead I used plain old return Redirect(url); Hope this works for you.
Unit Testing Surface Controllers
Hi,
I am trying to implement unit testing for a surface controller. The GET method tries to read some properties of the CurrentPage and POST method tries to redirect to the ChildPage of the CurrentPage. The problem I am encountering is I can never get the UmbracoContext in my unit tests. Has someone encountered and solved this? Any help much appreciated
This is an example of what my code will do on POST
Hi Poornima.
Instead of using
CurrentPage
, use theUmbracoHelper.AssignedContentItem
. Easier to mock.Instructions on how tro mock the UmbracoHelper is found here: https://our.umbraco.com/documentation/Implementation/Unit-Testing/
Cheers!
Thanks Dennis, will give it a shot..
Hi Poornima. Based on your example code (and our DM conversation on LinkedIn) it created an example of how a test for your example could look like.
The base class
UmbracoBaseTest
is the same base class I mention on this page: https://our.umbraco.com/documentation/Implementation/Unit-Testing/I ended up ditching
RedirectToUmbracoPageResult
because it turned out to be quite hard to Assert (queryStringValues is a private field, Url fields uses static resolver Current to resolve current page instead of DI), instead I used plain oldreturn Redirect(url);
Hope this works for you.Have a great day and stay safe!
Thanks a lot Dennis. Much much appreciated :-)
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.