Problems with unit testing in asp.net mvc? - unit-testing

UPDATE: SO I am getting the error whenever I have all meta tags like HostType,AspNetDevelopmentServerHost,URLToTest. So when I comment these tags I can run the test but I need to have these tags to have the connection string available for controller to connect to database.
I created a basic unit test by just right clicking on the action in asp.net mvc and saying Create unit tests...I am just trying to run a basic unit test.I am getting this error -
The test adapter 'WebHostAdapter' threw an exception while running test 'IndexTest'. The web site could not be configured correctly; getting ASP.NET process information failed. Requesting 'http://localhost:55767/VSEnterpriseHelper.axd' returned an error: The remote server returned an error: (500) Internal Server Error.
This is my method -
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\\Users\\Administrator\\Desktop\\MyWebsite\\Websites\\Customer1\\Customer1", "/")]
[UrlToTest("http://localhost:55767/Admin/Dashboard")]
public void IndexTest()
{
DashboardController target = new DashboardController(); // TODO: Initialize to an appropriate value
string id = string.Empty; // TODO: Initialize to an appropriate value
ActionResult expected = null; // TODO: Initialize to an appropriate value
ActionResult actual;
actual = target.Index(id);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
Any ideas what would be the problem here ? I tried to google but didnt get a good solution for my problem. I am using VS2010 Ultimate and asp.net mvc 2.0.

I created a basic unit test by just right clicking on the action in asp.net mvc and saying Create unit tests..
When you do this on an ASP.NET web application project (which is what MVC uses) Visual Studio will generate a ton of crap and will try to start the web server every time you want to run a single unit test. You don't want this.
Here are two possibilities:
When you start a new ASP.NET MVC project select that you want a unit test project in the default template (preferred).
You already have an ASP.NET MVC project and you want to add unit tests to it. In this case simply right click on the solution and add a new project of type Test Project. Now add reference to the ASP.NET MVC project you are testing and add a new unit test (Add New Item).

Related

Web Unit Tests not finding Url

I am using aspnetboilerplate 5.1.0.
In the ProjectName.Web.Tests I have run into a situation that I cannot solve.
I have set up web tests for my controller using [Fact] or [Theory].
When I attempt to run the tests using GetResponseAsString(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) found in the webtestbase class. All the tests fail.
Here is an example of my Test:
[Fact]
public async Task Index_Test()
{
//Act
var response = await GetResponseAsStringAsync(
GetUrl<HomeController>(nameof(HomeController.Index))
);
//Assert
response.ShouldNotBeNullOrEmpty();
}
The Tests all fail on this:
Message:
Shouldly.ShouldAssertException : response.StatusCode
should be
HttpStatusCode.OK
but was
HttpStatusCode.NotFound
I have other aspnetboilerplate projects in version 3.8.3 and 4.2.1 and the web tests work just fine. So I'm not sure why the server is not able to find the action methods on my controllers.
The service tests found in the ProjectName.Tests project run just fine.
I found the culprit. The problem I was experiencing was due to attempting to copy a project for web unit tests from one of the aspnetboilerplate project template repositories and updating all of the references and class names to match the names and namespaces in the destination VS solution.
I submitted a similar question on the aspnetboilerplate github account.
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/5463.
Ultimately, here is what happened.
After going through the same process with a newer project. I found that In the
class file that would by default be named AbpProjectNameWebTestBase.cs in the method
protected override IWebHostBuilder CreateWebHostBuilder()
{
return base
.CreateWebHostBuilder()
.UseContentRoot(ContentRootFolder.Value)
.UseSetting(WebHostDefaults.ApplicationKey, typeof(AbpProjectNameWebModule).Assembly.FullName);
}
I mistakenly replaced AbpProjectNameWebModule with AbpProjectNameTestModule instead of AbpProjectNameWebMvcModule. This was trying to use the Application Service Unit test project as the web project. Therefore it could not find any of the referenced URI's and therefore returned httpStatusCode.NotFound.
After fixing this reference. I started getting exceptions that pertained to the public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) method.
These were things like adding app.UseAuthentication() and app.UseAuthorization() as well as needing to add a Middleware to provide a ClaimsIdentity and ClaimsPrincipal for the context.User (i.e. app.UserMiddleware<TestAuthenticationMiddleware>())
Now, I am able to get my web unit tests to run as I had in previous versions.

Unit Testing Azure Functions with HttpRequestMessage

I'm running into a few issues when trying to unit test HTTP Trigger Azure Functions in Visual Studio. I've created a GitHub repo (https://github.com/ericdboyd/TestingAzureFunctions) with an example solution that contains both an Azure Function project and a Unit Test project that demonstrates the issues.
First, when I bring in Microsoft.AspNet.WebApi.Core it creates a conflict between System.Web.Http and Microsoft.AspNetCore.Mvc.WebApiCompatShim when trying to use IContentNegotiator. The only way around that was to alias WebApiCompatShim in the csproj file for the test project using the following:
<Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
<ReferencePath Condition="'%(FileName)' == 'Microsoft.AspNetCore.Mvc.WebApiCompatShim'">
<Aliases>webapicompatshim</Aliases>
</ReferencePath>
</ItemGroup>
Once I got past that error, I run into this issue which I haven't been able to get past. Using the HttpRequestMessage.CreateResponse extension method to return a response in the Azure Function, I get "No service for type 'System.Net.Http.Formatting.IContentNegotiator' has been registered." when I try to test it. I have tried to build a HttpRequestMessage that I think should work with that extension method using the following code which can also be found in the GitHub repo, but it fails, and I have worked on trying to get past this for several hours now.
IServiceCollection services = new ServiceCollection();
services.AddOptions();
services.AddSingleton(typeof(IContentNegotiator), typeof(DefaultContentNegotiator));
IServiceProvider serviceProvider = services.BuildServiceProvider();
var httpContext = new DefaultHttpContext {RequestServices = serviceProvider};
var httpConfiguration = new HttpConfiguration();
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Content = new StringContent(content, Encoding.UTF8, "application/json"),
Properties =
{
{ HttpPropertyKeys.HttpConfigurationKey, httpConfiguration },
{ nameof(HttpContext), httpContext}
}
};
If I don't use that CreateResponse extension method, and just create HttpResponseMessage objects, it works fine.
Just to set some additional context, I know this is not the best way to unit test the code being executed by the Azure Function. I'm unit testing that code much more granularly. But I want to be able to unit test the Azure Function that is performing the mapping between the http request and response to that logic.
There are two Azure Functions and two unit tests in the GitHub repo, one set with the extension method, one without to demonstrate the issue. But everything else is the same.
Not a direct answer to your problem, but it should help you go forward.
You are using Azure Functions v2 - .NET Standard version. This version is currently in beta, so it's a bit shady territory: the documentation is missing and some issues exist.
In V2 you are advised to use HttpRequest class and IActionResult instead of 'classic' HttpRequestMessage and HttpResponseMessage. The default template has a signature like this:
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req, TraceWriter log)
This should enable you to get rid of your shim and to unit test the functions similar to ASP.NET Core way.
Specify the jsonformatter while responding as below
req.CreateResponse(HttpStatusCode.OK, $"Hello, {name}", new JsonMediaTypeFormatter())

Ordered Selenium unit tests n

I have a small problem, I have created some Selenium tests. The problem is I can't order the testcases I have created. I know unit testing should not be ordered but this is what I need in my situation. I have to follow these steps: login first, create a new customer, change some details about the customer and finally log out.
Since there is no option to order unit tests in NUnit I can't execute this.
I already tried another option, to create a unittest project in Visual Studio, because Visual Studio 2012 has the ability to create a ordered unit test. But this is not working because I can't run a unit test while I am running my ASP.NET project. Another solution file is also not a good option because I want to verify my data after it has been submitted by a Selenium test.
Does someone of you have another solution to solve my problem?
If you want to test all of those steps in a specific order (and by the sounds of it, as a single session) then really it's more like an acceptance test you are talking about; and in that case it's not a sin to write more complex test methods and Assert your conditions after each step.
If you want to test each step in true isolation (a pure unit test) then each unit test must be capable of running by itself without any reference to any other tests; but when you're testing the actual site UI itself this isn't really an option for you.
Of course if you really you want to have every single test somehow setup every single dependency without reference to any other actions (e.g in the last test you would need to fake the login token, your data layer will have to pretend that you added a new customer, etc. A lot of work for dubious benefit...)
I say this based on the assumption that you already have unit tests written for the server-side controllers, layers, models, etc, that you run without any reference to the actual site running in a browser and are therefore confident that the various back-end part of your site do what they are supposed to do
In your case I'd recommend more of a hybrid integration/acceptance test
void Login(IWebDriver driver)
{
//use driver to open browser, navigate to login page, type user/password into box and press enter
}
void CreateNewCustomer(IWebDriver driver)
{
Login(driver);
//and then use driver to click "Create Customer" link, etc, etc
}
void EditNewlyCreatedCustomer(IWebDriver driver)
{
Login(driver);
CreateNewCustomer(driver);
//do your selenium stuff..
}
and then your test methods:
[Test]
void Login_DoesWhatIExpect()
{
var driver = new InternetExplorerDriver("your Login URL here");
Login(driver);
Assert(Something);
}
[Test]
void CreateNewCustomer_WorksProperly()
{
var driver = new InternetExplorerDriver("your Login URL here");
CreateNewCustomer(driver);
Assert(Something);
}
[Test]
void EditNewlyCreatedCustomer_DoesntExplodeTheServer()
{
var driver = new InternetExplorerDriver("your Login URL here");
EditNewlyCreatedCustomer(driver);
Assert(Something);
}
In this way the order of the specific tests do not matter; certainly if the Login test fails then the CreateNewCustomer and EditNewlyCreatedCustomer tests will also fail but that's actually irrelevant in this case as you are testing an entire "thread" of operation

How to mock g.message while writing unit test for grails controller

I am using grails version 1.3.7. In my application in controller, I am making use of messages.properties and fetching the value of the property as
g.message(code:messageKey, args:msgParamsArr)
But when I started writing unit tests for the action in the controller, it gave me errors.
Please can you help me out to understand how to mock g.message exactly so that the existing code will fetch the message properties from messages.properties only.
You can mock it with:
controller.metaClass.message = { message ->
message.code
}
You can include message.args too if you want to just validate the arguments with .contains().
This works like a champ in Grails 2.4.5:
controller.metaClass.message = { Map attrs -> attrs.toString() }

unit/integration testing of controllers and views using MvcContrib throws error when run

Am fairly new to the world of testing MVC 4 Web Applications and have been attempting to unit test views and controllers to see whether for a given controller that an action renders a particular view, I have been using MvcContrib TestHelper to try to simply the process of testing the application but so far have been unable to get the test to pass.
When the test is run I receive the error Expected view name was 'index' actual was ''
Currently I am running this test method:
[TestMethod]
public void AMAC_Controller_Renders_Index_View()
{
var builder = new TestControllerBuilder();
var controller = new AMACController();
builder.InitializeController(controller);
var result = controller.Index();
result.AssertViewRendered().ForView("index").WithViewData<AMACEnquiryModel>();
}
the controller and model are both currently in use by the application, was wondering if you could give any advice on how get this test working, I have modified previously when I have done this I get another error that the route name already exists in the collection.
After getting some advice from one of the contributors of the MvcContrib project the reason the test wasn't passing was because I was passing the wrong data into the .ForView(), before I had .ForView("index") where the controller was actually passing View(model) so the value for .ForView() was actually an empty string so the assert now looks like this:
result.AssertViewRendered().ForView("").WithViewData<AMACEnquiryModel>();