I have started using xUnit for a sample .NET CORE MVC project and I am struggling with adding tests to a ViewComponent
which includes IOptions
and IHostingEnvironment
. It's a simple view component that returns values from the appsettings.json file and this itself works without issue.
appsettings.json Snippet:
"Application": {"Name": "My App","Version": "1.0.0","Author": "John Doe", "Description": "Just a template!"}
ViewComponent:
[ViewComponent(Name = "Footer")]
public class FooterViewComponent : ViewComponent
{
private readonly IOptions<AppSettings.Application> _app;
private readonly IHostingEnvironment _env;
public FooterViewComponent(IOptions<AppSettings.Application> app, IHostingEnvironment env)
{
_app = app;
_env = env;
}
public IViewComponentResult Invoke()
{
var vm = new FooterViewModel();
{
vm.AppName = _app.Value.Name;
vm.AppVersion = _app.Value.Version;
vm.AppEnvironment = _env.EnvironmentName;
}
return View(vm);
}
}
I would like to test that the return type is a ViewComponent
result and the View Model is not empty.
ViewComponent Test:
public class FooterViewComponentTest
{
public class Should
{
[Fact]
public void ReturnViewCompnentWithViewModel()
{
// Arrange
var viewComp = new FooterViewComponent(??????????);
// Act
var result = viewComp ??????????;
// Assert
Assert.IsType<ViewComponentResult>(result);
}
}
}
I'm still working on this and will edit my snippets with my findings. Does anybody have any suggestions and should I be writing the tests in this format?
With the well known Moq Framework you can write mock objects of the dependency abstractions and inject them in the constructor of the component like this:
public class FooterViewComponentTest
{
public class Should
{
[Fact]
public void ReturnViewCompnentWithViewModel()
{
// Arrange
var appSettings = new AppSettings.Application();
appSettings.AppName = "app";
appSettings.Version = "1.0";
var optionsMock = new Mock<IOptions<AppSettings.Application>>();
optionsMock.Setup(o => o.Value).Returns(appSettings);
var hostingMock = new Mock<IHostingEnvironment>();
hostingMock.Setup(h => h.Environment).Returns("Test");
var viewComp = new FooterViewComponent(optionsMock.Object, hostingMock.Object);
// Act
var result = viewComp.Invoke();
// Assert
Assert.IsType<ViewComponentResult>(result);
}
}
}
Reference Moq Quickstart to get a better understanding of how to use the mocking framework.