views:

201

answers:

1

I'm doing unit testing for our WCF RIA services, which have RequiresRole or RequiresAuthentication attributes attached to them. I've been able to test the Update, Insert, and Delete methods to ensure the attributes are properly set. This is done by mocking a IServiceProvider, creating a DomainServiceContext with that provider and the correct DomainOperationType, adding an IPrincipal service to the service provider and then running Submit() on the service with an appropriate ChangeSet. This seems to work well.

However, I have been unable to test Query calls. These are called via the Query() method on the service. So I am doing the same prep work as with the others (Creating the IServiceProvider, DomainServiceContext and IPrincipal) and trying to create an appropriate DomainOperationEntry and QueryDescription to pass to Query(). Unfortunately, I've not had any luck with this yet. The relevant code is:

string operationName = "GetUsers";
DomainServiceContext domainServiceContext = GetDomainServiceContext(
    authenticate: false,
    operationType: DomainOperationType.Query);
DomainOperationQuery operationQuery = mocks.DynamicMock<DomainOperationEntry>(
    typeof(UserService), operationName, DomainOperation.Query,
    typeof(IQueryable<User>), new List<DomainOperationParameter>(),
    new AttributeCollection());
mocks.ReplayAll();

service.Initialize(domainServiceContext);

int totalCount;
IEnumerable<ValidationResult> validationErrors;
QueryDescription = new QueryDescription(operationEntry);

service.Query(queryDescription, out ValidatoinErrors, out TotalCount);

This should throw an UnauthorizedAccessException, when RequiresAuthentication is set on the GetUsers query. However, I don't get anything, regardless of whether the attribute is set. Using the debugger with a breakpoint set on the GetUsers method I can see that method is never called. My guess is I've got the operationName wrong. But I don't know whether that's the problem, or, if it is, what I should change it to.

Does anyone have any insight on this? I've searched all through MSDN and done Google searches and searched here extensively. I've got nothing so far.

A: 

I think there are two things to do when unit testing authorization:

First, check that the right rules have been applied. You don't have to execute the rule for this. Reflection tells you if the right rule has been applied. That is a by-product of the fact that rules are declaratively applied. More specifically, you'd use a higher level API above and beyond reflection - DomainServiceDescription against a DomainService type.

Next, test the rule does what it is supposed to do. For this create a mock implementation of IPrincipal, and an AuthorizationContext, and call the IsAuthorized method of the AuthorizationAttribute (where each attribute corresponds to a rule that you want to unit test).

Hope that helps.

NikhilK
First, thanks for the response. I actually started doing the first test a while ago...just haven't checked here since. Second, I'm not exactly clear on how to do the second. I should test that, as an example, RequiresRole applied to an IPrincipal via an AuthorizationContext works when the IPrincipal has the right role? Obviously, I'd test a custom authorization rule, because I presume RequiresRole does work right :) In other words, test the authorization rule.
Michael Johnson