Test are passing and they shouldn't - asp.net-mvc-5

Before I added [Authorize] filters for each controller, I created test cases and made them pass. Now I have added said filter on each controller's method but they still pass, but I think they shouldn't since there is no logged user. Am I not seeing something?
PS: I haven't mocked Identity 2.0
Edit:
Basically I'm mocking a repository, through the unit of work pattern. In my unit test, I get a reference to the List the mock repository uses, in order to test.
[TestMethod]
public async Task CanCreateCustomerAndRedirectToDetails() {
// Arrange
Customer customer = NewCustomer(); // Gets a new customer that is NOT on the list
CustomerCreateViewModel viewModel = Mapper.Map<CustomerCreateViewModel>(customer); // Maps to viewmodel
// Act
RedirectToRouteResult result = (RedirectToRouteResult) await Controller.Create(viewModel); // Sends to controller
// Assert
// Up to this point, Customers is the mock repository's list. so it should contain the new created customer since the controller should call the insert method
// Normally, the assertion should pass. But after I implemented [Authorize] filter, I would expect the controller not to do anything (besides redirecting to login) and this test would fail
Assert.IsNotNull(Customers.FirstOrDefault(e => e.ID == customer.ID));
Assert.AreEqual("Details", result.RouteValues["action"].ToString());
}

There's nothing in your unit test which responds to or in any way examines the Authorize attribute. Or any attribute.
Attributes don't actually change the behavior of the method. They decorate the method in a way that other code (such as in a framework, like ASP.NET MVC) might recognize. The Authorize attribute is used by the ASP.NET MVC framework. But the attribute alone doesn't change the method.
MSTest doesn't use the Authorize attribute. So if you want to test its presence on the method, you'd need to examine it in some way. Though that shouldn't really be necessary. The functionality of the framework is already very thoroughly tested by its vendor.
All your test needs to be testing is the functionality of the method, which it is. You don't need to test the functionality of the ASP.NET Framework.
You can test attributes very effectively by unit testing the classes which define those attributes. So if you, for example, created a custom attribute (let's call it CustomAuthorize) then you would have a class defining that attribute (CustomAuthorizeAttribute) and you could unit test that class, separately from unit testing your controllers.

Related

Node.js express app architecture with testing

Creating new project with auto-testing feature.
It uses basic express.
The question is how to orginize the code in order to be able to test it properly. (with mocha)
Almost every controller needs to have access to the database in order to fetch some data to proceed. But while testing - reaching the actual database is unwanted.
There are two ways as I see:
Stubbing a function, which intends to read/write from/to database.
Building two separate controller builders, one of each will be used to reach it from the endpoints, another one from tests.
just like that:
let myController = new TargetController(AuthService, DatabaseService...);
myController.targetMethod()
let myTestController = new TargetController(FakeAuthService, FakeDatabaseService...);
myTestController.targetMethod() // This method will use fake services which doesnt have any remote connection functionality
Every property passed will be set to a private variable inside the constructor of the controller. And by aiming to this private variable we could not care about what type of call it is. Test or Production one.
Is that a good approach of should it be remade?
Alright, It's considered to be a good practice as it is actually a dependency injection pattern

Unit testing claims based authorization with ThinkTecture ClaimsAuthorizeAttribute

We are controlling access to our application's resources and actions by using ThinkTecture's MVC ClaimsAuthorizeAttribute and would like to be able to include some unit test coverage using Moq.
Ideally, I'd like to write a test which requests a controller action decorated with:
[ClaimsAuthorize("operation_x", "resource_1")]
... so as to enter our AuthorizationManager's CheckAccess override method during execution of the test.
Our CheckAccess override simply gets the action and resource from the incoming AuthorizationContext ("operation_x" and "resource_1") and determines whether the Principal has the resource/action combination as a claim and returns true if a match is found.
The test would pass or fail based on the result of our CheckAccess override.
Most of the examples I've found online are about unit testing custom Authorize attributes or testing whether a controller action has been decorated by an AuthzAttribute. There don't seem to be many examples of testing ThinkTecture's ClaimsAuthorize attribute.
Is it even possible to achieve what I've described? If so, please advise!
Thanks
You may be looking to do more work than necessary - you don't need to test ThinkTecture's ClaimsAuthorizeAttribute, because ThinkTecture have already done that. You should write tests which test your own code - namely the outcome of the actions performed inside your override of CheckAccess.
If you want to check whether the ThinkTecture attribute works as it should, you should look into setting up an integration test which causes the controller action in question to be invoked.

Global request/response interceptor

What would be the easiest way to setup a request/response interceptor in ServiceStack that would execute for a particular service?
A request filter (IHasRequestFilter) works fine but a response filter (IHasResponseFilter) is not triggered if the service returns non 2xx status code. I need to retrieve the status code returned by the method as well as the response DTO (if any).
A custom ServiceRunner and overriding the OnBeforeExecute and OnAfterExecute methods seems to work fine but I find it pretty intrusive as the service runner need to be replaced for the entire application and I couldn't find a way clean way to isolate per functionality the tasks that need to be executed in those methods.
Is there some extension point in ServiceStack that I am missing that would allow me to execute some code before each service method and after each service method? A plugin would be ideal but how can I subscribe to some fictitious BeforeExecute and AfterExecute methods that would allow me to run some custom code?
UPDATE:
Just after posting the question I found out that global response filters are executed no matter what status code is returned by the service which is exactly what I needed. So one last question: Is it possible to retrieve the service type that will handle the request in a request filter? I need to check whether this service is decorated by some custom marker attribute.
I have found out a solution to my question about how to retrieve the service type in a custom request/response filter:
appHost.RequestFilters.Add((req, res, requestDto) =>
{
var metadata = EndpointHost.Metadata;
Type serviceType = metadata.GetServiceTypeByRequest(requestDto.GetType());
...
}
A custom ServiceRunner and overriding the OnBeforeExecute and OnAfterExecute methods seems to work fine but I find it pretty intrusive as the service runner need to be replaced for the entire application
Quick note, you can opt-in and choose only what requests should use a custom service runner, e.g:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
return useCustomRunner(actionContext.RequestType)
? new MyServiceRunner<TRequest>(this, actionContext)
: base.CreateServiceRunner<TRequest>(actionContext);
}
IHttpRequest has OperationName. I think thats what you are after.

Mocking Azure RoleEnvironment API with Microsoft Fakes

I'm trying to mock the Azure RoleEnvironment API with Microsoft Fakes. The problem is that I can't find a way to arrange the shims/stubs so that I can exercise the code in a unit test.
For instance, suppose I have the following code:
using Microsoft.WindowsAzure.ServiceRuntime;
// ...
Role role = RoleEnvironment.CurrentRoleInstance.Role;
int count = role.Instances.Count;
How would I mock the above with Fakes so that I can run it in a unit test?
So far my attempts fail because the RoleInstance class appears to have abstract properties with internal setters which prevents me from deriving a class from RoleInstance. This in turn prevents me from providing a shim for RoleEnvironment.CurrentRoleInstance.
BTW, I'm fully aware that relying too much on Fakes can be considered harmful. The thing is, I already have a wrapper for RoleEnvironment, together with production and test implementations. The code I'm trying to mock is in the production implementation which I want to test as well.
Unfortunately, I don't believe it is possible to isolate this code with Microsoft Fakes today. Normally, you would want to shim the RoleEnvironment.CurrentRoleInstance property to return a stub RoleInstance, that returns a stub Role. We can shim the CurrentRoleInstance property. But as you pointed out, both RoleInstance and Role are abstract classes with internal constructors, which we cannot stub with the current version of Fakes.

How can I unit test a request filter using the ReturnAuthRequired extension method?

In a previous version of serviceStack I was able to write a request filter for authorization this filter used res.ReturnAuthRequired() when I could not authorize the user. In the current version of servicestack my unit tests now return a null reference exception because ReturnAuthRequired now calls httpRes.EndServiceStackRequest(false); which then calls EndpointHost.CompleteRequest(); How can I unit test this now that there is a reference to the EndpointHost global variable? Should I not use the extension method?
Yeah the callbacks are required to support proper finalization of resources used in the request - e.g. it's required for Funq's new Request Scope support.
Anyway I've added some null checks in this commit to make it friendlier when unit testing, which will be available from the next v3.96 release onwards.

Resources