How do I explicitly specify where a Nancy view is located?

582 views Asked by At

First of all I know what the problem is, I just don't know Nancy well enough to know how to fix it.

I have a unit test failing when as part of the appharbor build process. The same test also fails when NCrunch executes it. But, when executed by VS2012 it works fine.

The test looks like this:

[Test]
public void Get_Root_Should_Return_Status_OK()
{
    // Given
    var browser = new Browser(new Bootstrapper());

    // When
    var result = browser.Get("/");

    // Then
    Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}

HomeModule part handling the "/" route looks like this:

Get["/"] = _ => View["home.sshtml"];

home.sshtml is in the Views folder.

If I replace the above with:

Get["/"] = _ => "Hello World!;

Then the test goes green.

So plainly the problem is that when running the test in NCrunch and appharbor the home.sshtml file cannot be found.

How do I explicitly tell Nancy where the file is?

PS The view file is being copied to the output directory.

PPS I have also tried explicitly telling Nancy where the Views are like and that doesn't work either.

protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
    var directoryInfo = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
    if (directoryInfo != null)
        Environment.CurrentDirectory = directoryInfo.FullName;
    Conventions.ViewLocationConventions.Add((viewName, model, viewLocationContext) => String.Concat("Views/", viewName));
}
1

There are 1 answers

0
Phill On BEST ANSWER

The problem is due to the fact that NCrunch doesn't copy the views to the output directory when it compiles and copies the bin directory for running the tests.

What you need to do is set the views to Copy Always, and then in your unit testing project add a IRootPathProvider implementation:

public class StaticPathProvider : IRootPathProvider
{
    public static string Path { get; set; }

    public string GetRootPath()
    {
        return Path;
    }
}

(Not entirely sure on the path, I can't remember, think it's just where the executing assembly is)

And register that in your bootstrapper for unit tests.

var browserParser = new Browser(with =>
{
  ...
  with.RootPathProvider<StaticPathProvider>();
  ...
});

Downside is when deploying you need to delete the view directory from your /bin directory.


The alternative is to do what you've already done, embed your views.