testing ASP.net MVC 3 business/data logic - asp.net

What is the best way to test data access layers and business logic in mvc 3 solutions?
I currently have a project where I am using repository classes to access databases, which in turn use hibernate. When I try to create a unit test for them in the auto generated unit tests, they always fail since the configuration for nhibernate is in web.config and and it doesnt try to look there. What am i doing wrong? This particular method returns this error
"The Web request 'http://localhost:35601/' completed
successfully without running the test"
The test methods look like this
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\\Users\\...", "/")]
[UrlToTest("http://localhost:35601/")]
public void GetByIdTest()
{
string someid= "..";
SomeObj actual = MyRepository.GetById(someid);
Assert.AreEqual(some, SomeObj.id);
}
How do i get this to work properly?

Putting the settings in the app.config should solve the issue you posed above however, the more correct answer is that you should be using a mocking framework to mock the nHibernate session.
The fact that you found an area that you would need to change to accomodate testing is great!!! That is one advantage of unit testing; you find coupling in your code that should be refactored.
I found another post that addresses what you are trying to do directly Mocking an NHibernate ISession with Moq. There are two answers in the post that offer to approaches which may be helpful.
I hope this helps. I havent used nHibernate so I can't speak authoritatively about it or that the link above will provide you with an answer, but each answer has ten upvotes so it looks like it was a solid post!

Related

Cannot resolve dependency in a custom ValidationAttribute, IServiceProvider is set to null on the ValidatationContontext parameter

An ASP.NET Core 2.1 MVC app, using Autofac following their documentation on setup (https://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html).
I am trying to resolve a dependency in a custom ValidationAttribute. The returned value from valicationContext.GetService is always returning null. Inspecting the validatationContext the private member serviceProvider is always null.
what am I missing in the setup that this isnt working. The dependancies resolve everywhere else in the app, just not in the ValidationAttributes.
public class MyCustomAttribute : ValidationAttribute
{
public MyCustomAttribute ()
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// THIS IS ALWAYS RETURNING NULL
var IMyService service = (IMyService)validationContext.GetService(typeof(IMyService));
return ValidationResult.Success;
}
}
I can't say I've tried this before, but doing some searching I found this issue which seems to indicate that the service provider (not the ServiceContainer property, but the service provider that will respond to GetService calls) should always be populated. Granted, that's from an archived repo from early on in .NET Core, but it should still hold.
Looking at the source for ValidationContext I see that the private serviceProvider field is actually a function that needs to be instantiated somewhere; it's not actually a reference to a provider proper. That means if it's null, one of two things is happening:
The path through ASP.NET Core that's instantiating that ValidationContext is not passing in the IServiceProvider required to provide services.
Something is broken.
If it's #1, I'd guess there are a variety of potential reasons. I'd think about things like...
The attribute is being used by something running outside the "ASP.NET Pipeline" - like a manually invoked validation or possibly something at application startup where there's no request at the moment.
The attribute is being used in a test where the full pipeline isn't in effect.
Something like that. I'm not saying this is what's happening, but I've seen questions like this before where it appears something isn't working right when it's actually an application code problem. For example, there are lots of questions about why "instance-per-request" dependencies aren't working and it turns out the code is running on a background thread where there's no request so... yeah. I don't know how your app works, but that sort of "I'm doing something I forgot to mention because I didn't think it was relevant" stuff comes into play here.
Let's assume you've got a super vanilla ASP.NET Core app, though. Based on the issue I mentioned earlier and the code you've posted, this looks like it should work but it's not. There shouldn't be anything you need to wire up for this, it should just work. Given that, you might want to file an issue about it. You may have found something that legitimately isn't working.
Before you do that, you might want to debug a little more. You can step right into ASP.NET Core source code and that could help you figure out what's up. The article I linked there explains how to set it up. It's not a two step process and needs screen shots to help or I'd put it right in here.
Set a breakpoint on your failing statement up there and then switch over to the Visual Studio "call stack" window. Click on the call stack frames higher up in the stack and see what's actually creating that context object. With a little clicking around and intuition you can probably figure out where the issue is. Maybe it'll point to something in your app you didn't realize you were doing, maybe it'll point to a bug in ASP.NET Core. If it's a bug in ASP.NET Core, having the information you found from your debugging session will be really helpful to that team.
Finally, I'd be remiss if I didn't mention that manually resolving a service in an attribute like this is technically service location rather than dependency injection and it'd be a better all-around solution if you avoided it entirely. There's an extremely similar question to yours right here walking through how to get around this with Simple Injector, though the principle holds for Autofac, too. Setting up model validators and using a model validator provider rather than attributes might be a better, more testable way to go. The answer in that question has more explanation on this.

Using multiple ObjectContexts in Entity Framework 4 with the repository/uow pattern

i am using EF4 and StructureMap in an asp.net web application. I am using the repository/unit of work patterns as detailed in this post. In the code, there is a line that delegates the setup of an ObjectContext in global.asax.
EntityUnitOfWorkFactory.SetObjectContext(() => new MyObjectContext());
On the web page code-behind, you can create a generic repository interface like so ...
IRepository<MyPocoObject> ds = ObjectFactory.GetInstance<IRepository<MyPocoObject>>();
My question is what is a good approach to refactoring this code so that I can use more than one ObjectContext and differentiate between them in the code-behind? Basically i have two databases/entity models in my application and need to query them both on the same page.
The Unit of Work is used to manage persistence across multiple repositories, not multiple object contexts.
You're not going to be able to persist changes across multiple contexts using a unit of work, as the UoW is simply implemented as a wrapper for a ObjectContext. Therefore, you'll need two unit of works.
Overall, things are going to get messy. You're going to have two OCs newed up and disposed each HTTP request, not to mention transaction management is going to be a nightmare.
Must you have two ObjectContexts? What is the reasoning for this? If it's for scalability, don't bother; it's going to be too painful for other things like your repository, unit of work and http scope management.
It's hard to provide good advice without seeing how you have your repositories set up.
Try creating wrapper classes for each object context, each implementing IUnitOfWork and a secondary unique interface (IEfSqlContext1, etc which represents one of your models/contexts).
Then you can inject whichever context you want.
As I said though, try and avoid having two EDMX/Contexts. It's more trouble than it's worth.

WCF Services - splitting code into multiple classes

I'm currently looking at developing a WCF Service for the first time, but am a bit confused.
Say I've got a windows application that is going to call into this web service, that service is then going to call our data methods to retrieve and save the data.
Now, say for example we have 2 classes in our solution, Customer and Product. Do all methods within the service have to go into the same class file (e.g. MyService.svc), or can they be split into several classes replicating the main data layer, i.e. Customer.cs and Product.cs. If they can be split, how do these get called from within the windows forms application? Would each class be a different end point?
At the moment I can access the methods within the main class (e.g. MyService.svc), but I can't see any of the methods in the other classes, even though I have attributed them with "ServiceContract" and "OperationContract".
I have a feeling I'm missing something simple somewhere, just not sure what.
I would be grateful if some nice person could point me in the direction of a tutorial on doing this, as every tutorial I've found only includes the single class :)
Thanks in advance.
What you need to define is Data Contracts for your service
Theoretically, these data contracts could be your business entities (since 3.5 SP1 and its WCF poco support)
It's better though to create separate entities for your service and then to create conversion classes that can convert your business entities into service entities and the other way around
Actually, after loads of searching, I finally seemed to find what I was looking for just after posting my question (typical).
I've found the following page - http://www.scribd.com/doc/13136057/ChapterImplementing-a-WCF-Service-in-the-Real-World
Although I've not gone through it yet, it does look like it will cover what I'm after.
Apologies for wasting anyones time :) Hopefully this will be useful to someone else looking for the same thing.
It sounds like you only need one service. However, if you need to create multiple services. Consider this as an example.
[ServiceContract(Name = "Utility", Namespace = Constants.COMMON_SERVICE_NAMESPACE)]
public interface IService
[ServiceContract(Name="Documents", Namespace = Constants.DOCUMENTS_SERVICE_NAMESPACE)]
public interface IDocumentService
[ServiceContract(Name = "Lists", Namespace = Constants.LISTS_SERVICE_NAMESPACE)]
public interface IListService
Remember that you can create multiple data contracts inside a single service, and it is the best solution for a method that will require a reference to Customer(s) and Product(s).
It might help to take a look at MSDN's data contract example here.

How can generate views in asp.net-mvc unit tests?

Im trying to generate views in unit tests but i can't get around the missing VirtualPathProvider. Most viewengines use the VirtualPathProviderViewEngine base class that gets the provider from the current HostingEnvironment.
protected VirtualPathProvider VirtualPathProvider {
get {
if (_vpp == null) {
_vpp = HostingEnvironment.VirtualPathProvider;
}
return _vpp;
}
set {
_vpp = value;
}
}
In unit tests there is no HostingEnvironment, even if i create one there is no current VirtualPathProvider.
How can i workaround this problem? Do i have to create a custom FakeWebFormViewEngine?
There are features coming in VS Team System 2010 for the Acceptance Testing which would be appropriate for what you are trying to do. As mentioned by Gregory A Beamer Unit tests for MVC are done to the controller. You can also test the Model depending on how you implement your model.
This is where there is a lot of controversy. Some people look at the model as business entities where I look at them as representations of the model specific to the View. More of a View Model. Since there is no real functionality in my model I do not have to test it. I test my DAL, Business Logic Layer outside of the MVC. MVC really is all part of the presentation layer. It is layering of your Presentation not your application. You still layer your application.
As far as Unit testing goes the controller is where you test. You can test your model if there are methods that require testing. As for the views they are acceptance tested by users or through automation like Watin.
I tried to do this as well. Unfortunately, it is not just the VirtualPathProvider (VPP) that is the problem. The VPP is used to map the view or partial view to a physical path to determine the existance of the file. Unfortunately, the ViewContext ends up with the virtualpath, not the physical path, so when the view is rendered the Builder uses properties of the HostingEvnironment which does not exist.
If you are using a version of Visual Studio with Testing, then you could use a Web Unit Test. This will allow you to use the browser to call the URL and then parse the response to check for values.
Pardon me if this sounds ignorant, but what is the purpose of generating views? I may be missing something, but the primary focus of unit tests is "testing the unit". In a properly set up ASP.NET MVC application, the code that needs to be tested is in the controller and below. In fact, I would say, if properly developed, it is below.
The test of the view is a user acceptance test. I see nothing wrong with automating this, by any means, but I am not sure this is something that has to be done with a unit test.
Am I missing something?
You can try Ivonna for integration (and, to some extent, unit) testing your Views.

ASP.NET - How do you Unit Test WebControls?

Alright.
So I figure it's about time I get into unit testing, since everyone's been banging on about it for long enough. I've installed NUnit and gone through a few "intro to unit testing" type tutorials.
I'm currently putting together a small framework to help with the rebuild of one of our web apps, so I've created a VS2008 project for my framework and I want to unit test it as I go.
How on earth do I go about unit testing the WebControls? The methods are all protected or private, and since it's a framework, there isn't much else but WebControls.
Any pointers?
Burns
You can do model-view-controller or model-view-presenter type architectures without using a full blown framework. You already found out that unit-testing ui-components is difficult. There are ways around that but you probably don't want to go that route. Usually this will make your tests very hard to maintain, more maintenance nightmare's is something programmers can do without :-)
Try to separate out the functionality you want to test in a "controller" or "presenter" class. Then test that class. To make it more testable you can hide the usercontrol class (the view) behind an interface and make the controller or presenter talk to the view through the interface. That way you can mock up the view in your tests.
I know this sounds like a lot of work and it seems like a workaround but if you get used to this it's a realy nice architecture that makes it far easier to change ui behaviour. You can always start using a "real" mvc framework when you realy need it :-)
Ues the assembly:InternalsVisibleTo attribute and you'll be able to access those private members.
Put it in your webcontrol project's AssemblyInfo.cs (under Properties node)
[assembly:InternalsVisibleTo("YourTestProjectName")]
You have found the biggest pain point of ASP.NET. As far as sealed, private classes that hinder unit testing.
This is the main reason that TDD people will use a MVC framework (ASP.NET MVC, Castle MonoRail) as it provides a clear seperation from your view templates and your controller logic. The controllers are fully testable.
You could also look at testing components through the browser as a user would see them using a testing framework such as WebAii. I've seen it work and its pretty cool. I've also been told you can plug it into automated builds but I've not seen that as of yet.
Hope it helps ...
This is an old article by now, but I was using NUnitASP to write nunit tests for asp.net WebControls in 2004. That article gives a detailed example of testing a simple control using their concept of creating a corresponding "Tester" class that encapsulates the details of your control from you tests. The Tester can (should) also be in the same assembly as your control so can share some things between them (e.g. utility functions, constants, etc.).
I used the technique (and others use variants of the technique) still today to test very sophisticated controls.
I hope that is helpful.
The MVC framework mentioned above is the best way to test what the control does. However testing how it works is a bit different.
This is totally off the cuff but you could make the user control expose some protected methods and properties to return validation information and then have a testing user control inherit it. That control could populate fields, press buttons and what not. Kind of messy but it could work.
You can also take a look at this Rhino Igloo framework. It is a compromised MVC framework for WebForms.
Ivonna
can test WebControls in isolation, within the Asp.Net context
Just call session.GetControl("Path.ascx") and verify that it has all necessary properties.
You test them like this:
[Test]
public void ConditionQueryBuilderTest_RendersProperHtml()
{
var sw = new StringWriter();
var queryBuilder = new ConditionQueryBuilderStub
{
ID = "UnitTestbuilder",
QueryBuilderURL = #"\SomeAspxPage\SomeWebMethod",
ResetQueryBuilderURL = #"\SomeAspxPage\OnQueryBuilderReset",
FilterValuesCollection = new Dictionary<int, string> { {15, "Some Condition"}}
};
queryBuilder.RenderAllContents(new HtmlTextWriter(sw));
AppendLog(sw.ToString());
Assert.AreEqual(ExpectedHtml, sw.ToString()); // ExpectedHTML is the raw expected HTML
}
Here is my stub:
internal class ConditionQueryBuilderStub : ConditionQueryBuilder // ConditionQueryBuilder is a WebControl
{
internal void RenderAllContents(HtmlTextWriter writer)
{
RenderContents(writer);
}
}

Resources