Mocking Azure RoleEnvironment API with Microsoft Fakes - azure

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.

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

How best to mock S4 endpoints to do performance tests (load test)?

This is not related to cloud sdk per se, but more regarding mocking the s4 endpoints which we usually use c sdk to query.
We want to do this for our load test, where we would not want the load test to go till s4 endpoint. We are considering using wiremock, to mock the endpoints, but the question is, whether the mocking logic in wiremock itself will contribute not in an insignificant manner to the metrics we are taking. If it would, then the metric becomes somewhwat unreliable since we want the apps performance metric not the mock framework's.
Other approach would be to use a mock server application dedicated for this, so that from app we would not have to do any mocking. Just route the call to the mock server app(using a mock destination perhaps)
My question to you guys is, have you ever encountered this use case? Perhaps yourself, or maybe from a consumer of yours. I would like to know how other teams in SAP solved this problem.
Thanks,
Sachin
In cases like yours, where the entire system (including responses from external services) should be tested, we usually recommend using Wiremock.
This is, because Wiremock is rather easy to setup and works well-enough for regular testing scenarios.
However, as you also pointed out, Wiremock introduces significant runtime overhead for the tested code and, thus, rending performance measurements of any kind more or less useless.
Hence, you could try mocking the HttpClient using Mockito instead:
BasicHttpResponse page = new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"));
page.setEntity(new StringEntity("hello world!));
HttpClient httpClient = mock(HttpClient.class);
doReturn(page).when(httpClient).execute(any(HttpUriRequest.class));
This enables fine-grained control over what your applications retrieves from the mocked endpoint without introducing any kind of actual network actions.
Using the code shown above obviously requires your application under test to actually use the mocked httpClient.
Assuming you are using the SAP Cloud SDK in your application, this can be achieved by overriding the HttpClientCache used in the HttpClientAccessor with a custom implementation that returns your mocked client, like so:
class MockedHttpClientCache implements HttpClientCache
{
#Nonnull
#Override
public Try<HttpClient> tryGetHttpClient(#Nonnull final HttpDestinationProperties destination, #Nonnull final HttpClientFactory httpClientFactory) {
return Try.of(yourMockedClient);
}
#Nonnull
#Override
public Try<HttpClient> tryGetHttpClient(#Nonnull final HttpClientFactory httpClientFactory) {
return Try.of(yourMockedClient);
}
}
// in your test code:
HttpClientAccessor.setHttpClientCache(new MockedHttpClientCache());

Create AutoMapper in Test Project (including AutoMapper.Profile classes)

I have a .net core service api which uses AutoMapper, and in Startup::ConfigureServices the services collection uses the AddAutoMapper extension to perform all the initialization necessary for dependency injection of an IMapper interface, e.g. services.AddAutoMapper(typeof(Startup)); The way I understand it is that by doing this, scanning is done for any/all AutoMapper.Profile types in order to set up the IMapper for DI into other constructors. Works great.
Now I'm writing tests for the service, and am wondering how to create this IMapper outside of Startup? Mocking it seems pointless, I just want to use it, so how do I create an instance of what I need that utilizes all of the AutoMapper.Profiles I have set up?
I was able to get this working by simply creating a MapperConfiguration which points to the needed Profile classes:
var mapperConfig = new MapperConfiguration(cfg => cfg.AddProfile<TestProfile>());
IMapper _mapper = new Mapper(mapperConfig);

Test are passing and they shouldn't

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.

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.

Resources