Web API global setup code, also for unit tests - c#

Say I have some global application setup code, defined in my Global.asax, Application_Start. For example to disable certificate checking:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// (...)
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// (...)
}
}
Say I also have a unit test, which depends on the code above to be run. However in my unit test, Application_Start is not called as I'm instantiating the controller directly:
var controller = new TestSubjectController();
Is there some mechanism in ASP.NET or Web API that solves this problem? What would be the best way to define the setup code, preventing duplication in my code?
Research
I've went through multiple questions on SO already. Most of them focus on unit testing Application_Start itself, however that's not the goal here. Other questions tend to look at testing using the applications external (HTTP) interface, however I'd like being able to instantiate the controller directly in my unit tests.

In addition to Batavia's suggestion you could use a [TestInitialize] attributed method or your unit testing framework of choices's equivalent to call the common static method for all tests in a certain class which would reduce the duplication you're concerned about.

Related

How to identify when my code is testing in C#?

I am having troubles when testing a controller, because there are some lines at my Startup that are null when testing, I want to add a condition for run this lines only if it's not testing.
// Desired method that retrieves if testing
if (!this.isTesting())
{
SwaggerConfig.ConfigureServices(services, this.AuthConfiguration, this.ApiMetadata.Version);
}
The correct answer (although of no help): It should not be able to tell so. The application should to everything it does unaware if it is in productino or test.
However to test the application in a simpler setting, you can use fake modules or mock-up modules that are loaded instead of the heavy-weight production modules.
But in order to use that, you have to refactor your solution and use injection for instance.
Some links I found:
Designing with interfaces
Mock Objects
Some more on Mock objects
It really depends on which framework you use for testing. It can be MSTest, NUnit or whatever.
Rule of thumb, is that your application should not know whether it is tested. It means everything should be configured before actual testing through injection of interfaces. Simple example of how tests should be done:
//this service in need of tests. You must test it's methods.
public class ProductionService: IProductionService
{
private readonly IImSomeDependency _dep;
public ImTested(IImSomeDependency dep){ _dep = dep; }
public void PrintStr(string str)
{
Console.WriteLine(_dep.Format(str));
}
}
//this is stub dependency. It contains anything you need for particular test. Be it some data, some request, or just return NULL.
public class TestDependency : IImSomeDependency
{
public string Format(string str)
{
return "TEST:"+str;
}
}
//this is production, here you send SMS, Nuclear missle and everything else which cost you money and resources.
public class ProductionDependency : IImSomeDependency
{
public string Format(string str)
{
return "PROD:"+str;
}
}
When you run tests you configure system like so:
var service = new ProductionService(new TestDependency());
service.PrintStr("Hello world!");
When you run your production code you configure it like so:
var service = new ProductionService(new ProductionDependency());
service.PrintStr("Hello world!");
This way ProductionService is just doing his work, not knowing about what is inside it's dependencies and don't need "is it testing case №431" flag.
Please, do not use test environment flags inside code if possible.
UPDATE:
See #Mario_The_Spoon explanation for better understanding of dependency management.

Why ninject gets different Db instances in nunit?

I write integration tests for ASP.NET MVC based application, and I try to resolve ninject registration issue.
So for my ASP.NET MVC registration I have
kernel.Bind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InRequestScope();
Just to clarify CustomDbContext implements IUnitOfWork and ICustomDbContext.
With that registration i guarantee that i have one unique instance per request for CustomDbContext. That registration works properly in scope of ASP.NET.
The problem is when i write integration tests.
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
[Test]
public async Task Test()
{
// Arrange
var claaService = kernel.Get<IService>();
}
On set up step i load my composition root (which is in ASP.NET MVC project).
The problem is when i get IService (Implementation of IService.cs is Service.cs and that service has dependencies to IUnitOfWork.cs and IGenericRepository.cs. IGenericRepository.cs has dependency to ICustomDbContext).
At the end when i access IService i should have same instance of CustomDbContext (and as I said in works in scope of MVC).
I have tried to resolve it in child scope, but the result is the same (they still have different hash code):
using (var childKernel1 = new ChildKernel(kernel))
{
childKernel1.Rebind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InThreadScope();
var claaService = childKernel1.Get<IClassService>();
}
My questions are:
Why this is happening ?
How can I resolve it (it works if i do not use ninject, but i want to find a way with Ninject, even if i have to add additional configuration in integration tests) ?
Why this is happening ?
Ninject's scoping is limited to the lifetime of the container. You have setup the container to be created for each [Test] because you are using [SetUp].
This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
If you want to use the same container across multiple tests in the same [TestFixture] (assuming this because you said "instance is not the same", but you didn't mention same as what), you need to use [OneTimeSetup] instead.
This attribute is to identify methods that are called once prior to executing any of the tests in a fixture.
[OneTimeSetUp]
public void OneTimeSetUp()
{
kernel = NinjectConfig.CreateKernel();
}
This of course assumes all of your relevant integration tests are in a single class.
In short, your Ninject container is being re-initialized on every test, which means all instances it manages are also being re-initialized.

How to create a restful web service with TDD approach?

I've been given a task of creating a restful web service with JSON formating using WCF with the below methods using TDD approach which should store the Product as a text file on disk:
CreateProduct(Product product)
GetAProduct(int productId)
URI Templates:
POST to /MyService/Product
GET to /MyService/Product/{productId}
Creating the service and its web methods are the easy part but
How would you approach this task with TDD? You should create a test before creating the SUT codes.
The rules of unit tests say they should also be independent and repeatable.
I have a number of confusions and issues as below:
1) Should I write my unit tests against the actual service implementation by adding a reference to it or against the urls of the service (in which case I'd have to host and run the service)? Or both?
2)
I was thinking one approach could be just creating one test method inside which I create a product, call the CreateProduct() method, then calling the GetAProduct() method and asserting that the product which was sent is the one that I have received. On TearDown() event I just remove the product which was created.
But the issues I have with the above is that
It tests more than one feature so it's not really a unit test.
It doesn't check whether the data was stored on file correctly
Is it TDD?
If I create a separate unit test for each web method then for example for calling GetAProduct() web method, I'd have to put some test data stored physically on the server since it can't rely on the CreateProduct() unit tests. They should be able to run independently.
Please advice.
Thanks,
I'd suggest not worrying about the web service end points and focus on behavior of the system. For the sake of this discussion I'll drop all technical jargon and talk about what I see as the core business problem you're trying to solve: Creating a Product Catalog.
In order to do so, start by thinking through what a product catalog does, not the technical details about how to do it. Use that as your starting points for your tests.
public class ProductCatalogTest
{
[Test]
public void allowsNewProductsToBeAdded() {}
[Test]
public void allowsUpdatesToExistingProducts() {}
[Test]
public void allowsFindingSpecificProductsUsingSku () {}
}
I won't go into detail about how to implement the tests and production code here, but this is a starting point. Once you've got the ProductCatalog production class worked out, you can turn your attention to the technical details like making a web service and marshaling your JSON.
I'm not a .NET guy, so this will be largely pseudocode, but it probably winds up looking something like this.
public class ProductCatalogServiceTest
{
[Test]
public void acceptsSkuAsParameterOnGetRequest()
{
var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
var catalogService = new ProductCatalogService(mockCatalog);
catalogService.find("some-sku-from-url")
mockCatalog.assertFindWasCalledWith("some-sku-from-url");
}
[Test]
public void returnsJsonFromGetRequest()
{
var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
mockCatalog.findShouldReturn(new Product("some-sku-from-url"));
var mockResponse = new MockHttpResponse(); // Hand rolled mock here.
var catalogService = new ProductCatalogService(mockCatalog, mockResponse);
catalogService.find("some-sku-from-url")
mockCatalog.assertWriteWasCalledWith("{ 'sku': 'some-sku-from-url' }");
}
}
You've now tested end to end, and test drove the whole thing. I personally would test drive the business logic contained in ProductCatalog and likely skip testing the marshaling as it's likely to all be done by frameworks anyway and it takes little code to tie the controllers into the product catalog. Your mileage may vary.
Finally, while test driving the catalog, I would expect the code to be split into multiple classes and mocking comes into play there so they would be unit tested, not a large integration test. Again, that's a topic for another day.
Hope that helps!
Brandon
Well to answer your question what I would do is to write the test calling the rest service and use something like Rhino Mocks to arrange (i.e setup an expectation for the call), act (actually run the code which calls the unit to be tested and assert that you get back what you expect. You could mock out the expected results of the rest call. An actual test of the rest service from front to back would be an integration test not a unit test.
So to be clearer the unit test you need to write is a test around what actually calls the rest web service in the business logic...
Like this is your proposed implementation (lets pretend this hasn't even been written)
public class SomeClass
{
private IWebServiceProxy proxy;
public SomeClass(IWebServiceProxy proxy)
{
this.proxy = proxy;
}
public void PostTheProduct()
{
proxy.Post("/MyService/Product");
}
public void REstGetCall()
{
proxy.Get("/MyService/Product/{productId}");
}
}
This is one of the tests you might consider writing.
[TestFixture]
public class TestingOurCalls()
{
[Test]
public Void TestTheProductCall()
{
var webServiceProxy = MockRepository.GenerateMock<IWebServiceProxy>();
SomeClass someClass = new SomeClass(webServiceProxy);
webServiceProxy.Expect(p=>p.Post("/MyService/Product"));
someClass.PostTheProduct(Arg<string>.Is.Anything());
webServiceProxy.VerifyAllExpectations();
}
}

Learning TDD, always running into circular dependency

I started using TDD to improve my quality and the design of my code but I usually encounter a problem. I'll try to explain it through a simple example:
I try to implement a simple application using passive view design. This means that I try to make the view as dumb as possible. Let's consider an application, where the GUI has a button and a label. If the user presses the button, a file get created with one random line in it. Then the label displays whether the creation was successful or not.
The code might look like this:
IView interface: a single setter string property: Result
GUIEventListener class: OnUserButtonClick method which gets called from the GUI's button
FileSaver class: SaveFile method which gets called from the GUIEventListener
GUIController class: UpdateLabel method which gets called from the FileSaver class's SaveFile method with a parameter depending the success of the SaveFile method.
Instantiation looks like this:
View's ctor: View(GUIEventListener eventListener)
GUIEventListener's ctor: GUIEventListener(FileSaver fileSaver)
FileSaver's ctor: FileSaver(GUIController controller)
GUIController's ctor: GUIController(View view)
As you can clearly see, there's a circular dependency in the design.
I usually try to avoid using events, I don't like testing with them and I think this type of design is more self explanatory as it clearly states what are the relation of the classes.
I'v heard of IoC design style but I'm not really familiar with it.
What are my "sticking point" in TDD regarding this issue? I always end up running into this problem and I want to learn a proper pattern or principle to avoid it in the future.
GUIController class: UpdateLabel method which gets called from the FileSaver class's SaveFile
...
FileSaver's ctor: FileSaver(GUIController controller)
Here's the flaw in your design. The FileSaver should be agnostic of who calls it (read: shouldn't hold a reference to the layer underneath it), it should just do its job i.e. save a file and inform the world how the operation went - typically through a return value.
This not really related to TDD, except maybe TDD would have forced you to think in terms of the most basic behavior that is expected from a FileSaver and realize it is not its responsibility to update a label (see Single Responsibility Principle).
As for the other parts of your system, like Roy said they'll most often be difficult to test in TDD except for the Controller.
Unit testing UIs is often a problem, for many reasons... The way I've done it in the past few years on MVC projects is to simply unit-test only the Controllers and to later test the application hands-on.
Controllers can be unit-tested easily because they are logic classes just like any other and you can mock out the dependencies. UIs, especially for Web applications, are much tougher. You can use tools such as Selenium or WatiN but that is really integration/acceptance testing rather than unit testing.
Here's some further reading:
How to get started with Selenium Core and ASP.NET MVC
This is how ASP.NET MVC controller actions should be unit tested
Good luck!
I would get rid of the GUIEventListener class. Seems like a overkill to me.
Since the view knows when the button is clicked, let the view share its knowledge with the world:
public interface IView
{
void DisplayMessage(string message);
void AddButtonClickHandler(Action handler);
}
The FileSaver is even simpler:
public interface IFileSaver
{
Boolean SaveFileWithRandomLine();
}
Just for fun, let's create an interface for the controller:
public interface IController
{
}
And the controller implementation:
public class Controller : IController
{
public Controller(IView view, IFileSaver fileSaver)
{
}
}
OK, let's write the tests (I am using NUnit and Moq):
[TestFixture]
public class ControllerTest
{
private Controller controller;
private Mock<IFileSaver> fileSaver;
private Mock<IView> view;
private Action ButtonClickAction;
[SetUp]
public void SetUp()
{
view = new Mock<IView>();
//Let's store the delegate added to the view so we can invoke it later,
//simulating a click on the button
view.Setup((v) => v.AddButtonClickHandler(It.IsAny<Action>()))
.Callback<Action>((a) => ButtonClickAction = a);
fileSaver = new Mock<IFileSaver>();
controller = new Controller(view.Object, fileSaver.Object);
//This tests if a handler was added via AddButtonClickHandler
//via the Controller ctor.
view.VerifyAll();
}
[Test]
public void No_button_click_nothing_happens()
{
fileSaver.Setup(f => f.SaveFileWithRandomLine()).Returns(true);
view.Verify(v => v.DisplayMessage(It.IsAny<String>()), Times.Never());
}
[Test]
public void Say_it_worked()
{
fileSaver.Setup(f => f.SaveFileWithRandomLine()).Returns(true);
ButtonClickAction();
view.Verify(v => v.DisplayMessage("It worked!"));
}
[Test]
public void Say_it_failed()
{
fileSaver.Setup(f => f.SaveFileWithRandomLine()).Returns(false);
ButtonClickAction();
view.Verify(v => v.DisplayMessage("It failed!"));
}
}
I think the tests are pretty clear, but I don't know if you know Moq.
The full code for the Controller could look like the following (I just hammered it into one line, but you don't have to, of course):
public class Controller : IController
{
public Controller(IView view, IFileSaver fileSaver)
{
view.AddButtonClickHandler(() => view.DisplayMessage(fileSaver.SaveFileWithRandomLine() ? "It worked!" : "It failed!"));
}
}
As you can see, this way you are able to test the controller, and we don't have even startet to implement the View or the FileSaver. By using interfaces, they don't have to know each other.
The View knows nothing (except that somebody may be informed when the Button is clicked), it is as dump as possible. Note that no events pollute the interface, but if you're going to implement the View in WinForms, nothing stops you from using events inside the View-implementation. But nobody outside has to know, and so we don't need to test it.
The FileSaver just saves files and tells if it failed or not. It doesn't know about controllers and views.
The Controller puts everything together, without knowing about the implementations. It just knows the contracts. It knows about the View and the FileSaver.
With this design, we just test the behaviour of the controller. We ask: 'If the button was clicked, was the view informed that it should display that information?' and so on. You could add more tests to check if the Save-Method on the FileSaver were called by the Controller if you like.
A nice resource on this topic is The Build Your Own CAB Series by Jeremy Miller

WCF Service authorization patterns

I'm implementing a secure WCF service. Authentication is done using username / password or Windows credentials. The service is hosted in a Windows Service process. Now, I'm trying to find out the best way to implement authorization for each service operation.
For example, consider the following method:
public EntityInfo GetEntityInfo(string entityId);
As you may know, in WCF, there is an OperationContext object from which you can retrieve the security credentials passed in by the caller/client. Now,authentication would have already finished by the time the first line in the method is called. However, how do we implement authorization if the decision depends on the input data itself? For example, in the above case, say 'admin' users(whose permissions etc are stored in a database), are allowed to get entity info, and other users should not be allowed... where do we put the authorization checks?
Say we put it in the first line of the method like so:
CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext
Now, there are a couple of questions:
Do we validate the entityId (for example check null / empty value etc) BEFORE the authorization check or INSIDE the authorization check? In other words, if authorization checks should be included in every method, is that a good pattern? Which should happen first - argument validation or authorization?
How do we unit test a WCF service when authorization checks are all over the place like this, and we don't have an OperationContext in the unit test!? (Assuming I'm tryin to test this service class implementation directly without any of the WCF setup).
Any ideas guys?
For question 1, it's best to perform authorization first. That way, you don't leak validation error messages back to unauthorized users.
BTW, instead of using a home-grown authentication method (which I assume is what your CheckAccessPermission is), you might be able to hook up to WCF's out-of-the-box support for ASP.NET role providers. Once this is done, you perform authorization via OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole(). The PrimaryIdentity is an IPrincipal.
About question #2, I would do this using Dependency Injection and set up your service implementation something like this:
class MyService : IMyService
{
public MyService() : this(new UserAuthorization()) { }
public MyService(IAuthorization auth) { _auth = auth; }
private IAuthorization _auth;
public EntityInfo GetEntityInfo(string entityId)
{
_auth.CheckAccessPermission(PermissionType.GetEntity,
user, entityId);
//Get the entity info
}
}
Note that IAuthorization is an interface that you would define.
Because you are going to be testing the service type directly (that is, without running it inside the WCF hosting framework) you simply set up your service to use a dummy IAuthorization type that allows all calls. However, an even BETTER test is to mock the IAuthorization and test that it is called when and with the parameters that you expect. This allows you to test that your calls to the authorization methods are valid, along with the method itself.
Separating the authorization into it's own type also allows you to more easily test that it is correct in isolation. In my (albeit limited) experience, using DI "patterns" give you vastly better separation of concerns and testability in your types as well as leading to a cleaner interface (this is obviously open to debate).
My preferred mocking framework is RhinoMocks which is free and has very nice fluent interface but there are lots of others out there. If you'd like to know more about DI here are some good primers and .Net frameworks:
Martin Fowler on DI
Jeremy Miller on DI
Scott Hanselman's List of DI Containers
My personal favorite DI container: The Castle Project Windsor Container
For question 1, absolutely do authorization first. No code (within your control) should execute before authorization to maintain the tightest security. Paul's example above is excellent.
For question 2, you could handle this by subclassing your concrete service implementation. Make the true business logic implementation an abstract class with an abstract "CheckPermissions" method as you mention above. Then create 2 subclasses, one for WCF use, and one (very isolated in a non deployed DLL) which returns true (or whatever you'd like it to do in your unit testing).
Example (note, these shouldn't be in the same file or even DLL though!):
public abstract class MyServiceImpl
{
public void MyMethod(string entityId)
{
CheckPermissions(entityId);
//move along...
}
protected abstract bool CheckPermissions(string entityId);
}
public class MyServiceUnitTest
{
private bool CheckPermissions(string entityId)
{
return true;
}
}
public class MyServiceMyAuth
{
private bool CheckPermissions(string entityId)
{
//do some custom authentication
return true;
}
}
Then your WCF deployment uses the class "MyServiceMyAuth", and you do your unit testing against the other.

Categories

Resources