Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Web Developer

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Nancy and VB.Net: The bootstrapperNancy and VB.Net: the razor view engine »
    comments

    Introduction

    In my previous post I made a Plantsmodule which had 2 routes. One of those routes had a problem when tried to put a string in the parameter and that was less than optimal. It was time for tests to make it easier on myself to test these kinds of things.

    The module

    So here is my module.

    1. Imports WebApplication2.Model
    2. Imports Nancy
    3.  
    4. Public Class PlantsModule
    5.     Inherits NancyModule
    6.  
    7.     Public Sub New()
    8.         MyBase.Get("/plants") = Function(parameters)
    9.                                     Return View(New PlantsModel() With {.Plants = New List(Of PlantModel) From {New PlantModel() With {.Id = 2, .Name = "test"}}})
    10.  
    11.                                 End Function
    12.         MyBase.Get("/plants/{Id}") = Function(parameters)
    13.                                          If parameters.id = 1 Then
    14.                                              Return View(New PlantModel() With {.Id = 1, .Name = "test"})
    15.                                          Else
    16.                                              Return View(New PlantModel() With {.Id = 2, .Name = "test"})
    17.                                          End If
    18.                                      End Function
    19.  
    20.     End Sub
    21.  
    22. End Class

    This one throws an exception when you enter abc or any other bad value.

    The tests

    To begin with you should nuget the Nancy.Testing package.

    Then you can use the Browser.

    For our purpose it would look something like this.

    1. Private _browser As Browser
    2.  
    3.     <SetUp()>
    4.     Public Sub FixtureSetup()
    5.         Dim configuration = A.Fake(Of IRazorConfiguration)()
    6.         Dim bootstrapper = New ConfigurableBootstrapper(Sub(config)
    7.                                                             config.Module(Of PlantsModule)()
    8.                                                             config.ViewEngine(New RazorViewEngine(configuration))
    9.                                                         End Sub)
    10.         _browser = New Browser(bootstrapper)
    11.     End Sub

    So we tell it what Module to use and we tell it what Engine to use. We also use FakeItEasy to make a mock for our RazorConfiguration. For the next part I got some help from this blogpost by Jef Claes.

    if you leave out the Engine you will get this error.

    System.Exception : ConfigurableBootstrapper Exception
    ----> Nancy.RequestExecutionException : Oh noes!
    ----> Nancy.ViewEngines.ViewNotFoundException : Unable to locate view 'Plants'
    Currently available view engine extensions: sshtml,html,htm
    Locations inspected: ,,,,views/Plants/Plants,Plants/Plants,views/Plants,Plants
    Root path: E:\Users\christiaan\AppData\Local\NCrunch\7084\61\WebApplication2\bin

    Do you notice how it does not mention cshtml or vbhtml in view engine extensions? That is solved by telling it what engine to use.

    In theory that should work but you will get this error when you try it.

    System.Exception : ConfigurableBootstrapper Exception
    ----> Nancy.RequestExecutionException : Oh noes!
    ----> Nancy.ViewEngines.ViewNotFoundException : Unable to locate view 'Plants'
    Currently available view engine extensions: sshtml,html,htm,cshtml,vbhtml
    Locations inspected: ,,,,views/Plants/Plants,Plants/Plants,views/Plants,Plants
    Root path: E:\Users\christiaan\AppData\Local\NCrunch\7084\61\WebApplication2\bin

    That is solved by the RootPathProvider we find in the blogpost by Jef Claes. In VB.Net that would look like this.

    1. Imports System.IO
    2. Imports Nancy
    3.  
    4. Public Class RootPathProvider
    5.     Implements IRootPathProvider
    6.  
    7.     Private Shared _cachedRootPath As String
    8.  
    9.     Public Function GetRootPath() As String Implements IRootPathProvider.GetRootPath
    10.         If Not String.IsNullOrEmpty(_cachedRootPath) Then Return _cachedRootPath
    11.         Dim currentDirectory = New DirectoryInfo(Environment.CurrentDirectory)
    12.         Dim rootPathFound = False
    13.         While Not rootPathFound
    14.             Dim directoriesContainingViewFolder = currentDirectory.GetDirectories("Views", SearchOption.AllDirectories)
    15.             If directoriesContainingViewFolder.Any() Then
    16.                 _cachedRootPath = directoriesContainingViewFolder.First().FullName
    17.                 rootPathFound = True
    18.             End If
    19.             currentDirectory = currentDirectory.Parent
    20.         End While
    21.         Return _cachedRootPath
    22.     End Function
    23.  
    24.     Public Function Equals1(obj As Object) As Boolean Implements IHideObjectMembers.Equals
    25.  
    26.     End Function
    27.  
    28.     Public Function GetHashCode1() As Integer Implements IHideObjectMembers.GetHashCode
    29.  
    30.     End Function
    31.  
    32.     Public Function GetType1() As Type Implements IHideObjectMembers.GetType
    33.  
    34.     End Function
    35.  
    36.     Public Function ToString1() As String Implements IHideObjectMembers.ToString
    37.  
    38.     End Function
    39. End Class

    The above presumes your views are in a Views subfolder. Which they are of course.
    And now we can start writing tests.

    1. <Test>
    2.     Public Sub IfPlantsRouteReturnsStatusCodeOk()
    3.         Dim result = _browser.Get("/plants", Sub(x)
    4.                                                  x.HttpRequest()
    5.                                              End Sub)
    6.         Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
    7.     End Sub
    8.  
    9.     <Test>
    10.     Public Sub IfPlantWithId1RouteReturnsStatusCodeOk()
    11.         Dim result = _browser.Get("/plants/1", Sub(x)
    12.                                                    x.HttpRequest()
    13.                                                End Sub)
    14.         Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
    15.     End Sub
    16.  
    17.     <Test>
    18.     Public Sub IfPlantWithIdabcRouteReturnsStatusCodeOk()
    19.         Dim result = _browser.Get("/plants/abc", Sub(x)
    20.                                                      x.HttpRequest()
    21.                                                  End Sub)
    22.         Assert.AreEqual(HttpStatusCode.NotFound, result.StatusCode)
    23.     End Sub

    I just want to check if I get an ok code when it works and a not found when I do plants/abc

    But the last test fails. With this exception.

    1. System.Exception : ConfigurableBootstrapper Exception
    2.   ----> Nancy.RequestExecutionException : Oh noes!
    3.   ----> System.InvalidCastException : Conversion from string "abc" to type 'Double' is not valid.
    4.   ----> System.FormatException : Input string was not in a correct format.

    Time to change our Module. And do the simplest thing to make our test pass.

    1. Imports WebApplication2.Model
    2. Imports Nancy
    3.  
    4. Public Class PlantsModule
    5.     Inherits NancyModule
    6.  
    7.     Public Sub New()
    8.         MyBase.Get("/plants") = Function(parameters)
    9.                                     Return View(New PlantsModel() With {.Plants = New List(Of PlantModel) From {New PlantModel() With {.Id = 2, .Name = "test"}}})
    10.  
    11.                                 End Function
    12.         MyBase.Get("/plants/{Id}") = Function(parameters)
    13.                                          If Not IsNumeric(parameters.id) Then Return HttpStatusCode.NotFound
    14.                                          If parameters.id = 1 Then
    15.                                              Return View(New PlantModel() With {.Id = 1, .Name = "test"})
    16.                                          Else
    17.                                              Return View(New PlantModel() With {.Id = 2, .Name = "test"})
    18.                                          End If
    19.                                      End Function
    20.  
    21.     End Sub
    22.  
    23. End Class

    And now all three of our tests pass.

    Don't worry I can write more tests.

    Conclusion

    I figured it out, so it isn't that hard ;-).

    Update

    Since version 0.15 the viewengine also needs a textresource. So now the setup looks like this.

    1. <SetUp()>
    2.         Public Sub FixtureSetup()
    3.             Dim configuration = A.Fake(Of IRazorConfiguration)()
    4.             Dim textResource = A.Fake(Of ITextResource)()
    5.             Dim bootstrapper = New ConfigurableBootstrapper(Sub(config)
    6.                                                                 config.Module(Of PlantsModule)()
    7.                                                                 config.Dependency(Of ITextResource)(textResource)
    8.                                                                 config.ViewEngine(New RazorViewEngine(configuration, textResource))
    9.                                                             End Sub)
    10.             _browser = New Browser(bootstrapper)
    11.         End Sub

    About the Author

    User bio imageChris is awesome.
    Social SitingsTwitterHomePageLTD RSS Feed
    nancy, vb.net
    InstapaperVote on HN

    No feedback yet

    Leave a comment


    Your email address will not be revealed on this site.

    To mislead the spambots.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)