Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Poornima Nayar 94 posts 243 karma points MVP 2x c-trib
    May 14, 2020 @ 07:58
    Poornima Nayar
    0

    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

    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() + "&registrationId=" + model.Id.ToString());
    }
    
  • Dennis Adolfi 1072 posts 6378 karma points MVP 2x c-trib
    May 14, 2020 @ 08:22
    Dennis Adolfi
    0

    Hi Poornima.

    Instead of using CurrentPage, use the UmbracoHelper.AssignedContentItem. Easier to mock.

    Instructions on how tro mock the UmbracoHelper is found here: https://our.umbraco.com/documentation/Implementation/Unit-Testing/

    Cheers!

  • Poornima Nayar 94 posts 243 karma points MVP 2x c-trib
    May 14, 2020 @ 08:26
    Poornima Nayar
    0

    Thanks Dennis, will give it a shot..

  • Dennis Adolfi 1072 posts 6378 karma points MVP 2x c-trib
    May 18, 2020 @ 05:45
    Dennis Adolfi
    100

    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/

    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&registrationId=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}&registrationId={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.

    Have a great day and stay safe!

  • Poornima Nayar 94 posts 243 karma points MVP 2x c-trib
    May 18, 2020 @ 08:34
    Poornima Nayar
    1

    Thanks a lot Dennis. Much much appreciated :-)

  • 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.

Please Sign in or register to post replies