Here is my endpoint in akka-http:
private val route = Route.asyncHandler(
pathPrefix("v0") {
headerValueByType[JWTTokenObject](()) { jwtHeader =>
mapRequest(authorize(jwtHeader.value)) {
authenticateOrRejectWithChallenge(authenticate(transactionId, _)) { claims =>
pathPrefix("v1"/Segment) { someValue =>
path("v3") {
post {
handleThisPostRequest(someValue)
}
}
}
}
}
}
)
This is one of the POST API which authenticates using JWT 'Bearer' token which is passed as a header value. I want to test this End To End. It is also calling DBs and third party services.
I am trying to add any API test framework so that I will be able to test this on any environments. Can you suggest any framework to achieve this type of integration tests where enviroment variables are involved in calling third party APIs.
Is it possible to test this using spray-testkit(Test API REST SCALA)? An example will be helpful. Thanks
Well, the Akka Testkit(https://doc.akka.io/docs/akka-http/current/routing-dsl/testkit.html) has a wonderful suite for doing route an Actor testing. I would suggest using it.
Take a look to how to handle the Authorization token: https://github.com/akka/akka-http/blob/main/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/SecurityDirectivesSpec.scala.
With respect to the environment variables: if you need that in your tests the code needs to call a remote service because is a integration or E2E test, make use of the capabilities of Scala config:
https://github.com/lightbend/config#optional-system-or-env-variable-overrides.
There are a lot of strategies about how to deal with testing in these kind of projects, but, in case ok Akka there are good resources to read about it.
Related
I have a .Net Core web API solution called ReportService, which calls another API endpoint (we can call this PayrollService) to get payroll reports. So my requirement is to mock the PayrollService using Wiremock.Net.
Also currently I have a automation test case written, which will directly call the ReportService controller and will execute all the service logic, and also classes which calls PayrollService and the DB layer logic and will get the HTTP result back from the ReportService.
Please note that the Automation test cases is a separate solution. So my requirement is to run the automation test cases like before on ReportService, and the payroll service will be mocked by Wiremock.
So, what are the changes that need to happen in the codebase? Do we have to change the url of the ReportService to be the Wiremock server base url in the ReportService solution? Please let us know, and please use the terms I have used in the question regarding the project names so I am clear.
Your assumption is indeed correct, you have make the base URL which is used by ReportService configurable.
So that for your unit / integration tests you can provide the URL on which the WireMock.Net server is running.
Example:
[Test]
public async Task ReportService_Should_Call_External_API_And_Get_Report()
{
// Arrange (start WireMock.Net server)
var server = WireMockServer.Start();
// Setup your mapping
server
.Given(Request.Create().WithPath("/foo").UsingGet())
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody(#"{ ""msg"": ""Hello world!"" }")
);
// Act (configure your ReportService to connect to the URL where WireMock.Net is running)
var reportService = new ReportService(server.Urls[0]});
var response = reportService.GetResport();
// Assert
Assert.Equal(response, ...); // Verify
}
I am using Spring Cloud Contract to create stubs for a REST service so I can test with a REST client. I have the stub runner working within a Spring Boot application, and it all works as expected. The problem I am having is that I'd like to see elements of the requests in the responses, to better simulate the eventual behavior of the REST service. For example, in this contract, I'd like what is passed in the "code" field in the request to appear regurgitated in the response:
package contracts
org.springframework.cloud.contract.spec.Contract.make {
request {
method('POST')
url $("/resource")
body ([
code : $(client(regex('[a-zA-Z0-9]{5,32}')))
])
}
response {
status 200
body([
code: ???
])
}
}
Obviously the input "code" can be anything that matches the regular expression, and so the actual value is unknown until runtime. Is there anything i can put in place of "???" to return the code submitted in the request ? I tried accessing, for example:
request.body.serverValue['code']
but that value it seems is generated at compile time, perhaps to enable the auto-generation of tests in ContractVerifierTest.java under generated-test-sources.
Can this be done ? Is this an appropriate use of Spring Cloud Contract ?
Currently, it's not supported. We prefer an approach where you have simpler contracts. If you need in a response a value from the request just hard code both the request and the response parts of the contract.
You can, however, file an issue and we can try to think of something in the future releases.
UPDATE:
With version 1.1.0 that's already possible. Check out the docs for more info - http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.1.0.RELEASE/#_referencing_request_from_response
So I am using Dustjs on Sailsjs for my project.
I am rendering the first page on the server, and then use the same template client-side.
Problem: My template contains a global sails service which doubles as a dustjs helper:
{#sails.services.globalutils.hyphenator str=title/}
But, on the client-side, I am unable to uyse this service. How can I export this service to the client without going for a JS solution? Can it be bundled with the dustjs template ?
A {#section} signals that Dust should look in the context provided to dust.render(). So as long as the hyphenator function doesn't have server-side dependencies, you can just bring it along in your client-side context. Sails services are just Javascript modules in the api/services folder, so try requireing the relevant module, grabbing its hyphenator property, and passing that along to the client to use in the client's render call.
{
"sails": {
"services": {
"globalutils": {
"hyphenator": function(chunk, context, bodies, params) {
// do some hyphenation
}
}
}
}
}
Of course, if hyphenator has logic that relies on the server, you can't just move it to the client. You could expose a server-side API that your script calls, and couple that with chunk.map to create an asynchronous Dust block.
I'm a novice programmer who is very new to both AngularJS and the practice of unit testing. I've spent hours trying to find the solution to this but I'm becoming increasingly more confused. If anyone could point me in the right direction I would greatly appreciate it. I'll try to be as descriptive as possible.
The situation is this:
I have created a service in AngularJS (Service A) that has a couple of functions. Each of these functions makes an $http GET request to a REST API and returns an $http promise object that contains JSON data. Within these functions, the URL is constructed through the implementation of another very simple service (Service B) that has been injected as a dependency into Service A. I have created a mock of Service B to isolate it from all of its dependencies. Both of these services are defined inside of the same module named "services". In this case, there is no real need for this dependency but I just want to understand how it works.
Using Jasmine, I would like to construct a unit test for Service A to ensure that the requests it is making to the API are constructed correctly and possibly if the correct JSON data is being returned. At the same time, I do not want any real API calls to be made.
This is what I know:
$httpBackend mock is what I need to be able to make fake calls to the API and it provides functionality to expect certain requests and return specified results.
I need to test the real Service A and inject the mock I've created of Service B. I know there are ways to do this using Jasmine Spies and $provide. I've also seen examples where sinon.js is used, and I'm not sure which is the best approach.
I will post my source code below, which is written in CoffeeScript.
Service A:
'use strict'
angular.module("services")
.service("ServiceA", ["$http", "ServiceB", ($http, ServiceB) ->
#Uses underscore.js to set this default attribute
defaults = withCredentials:true
getVarset: (itemName, options={}) ->
options.method = "GET"
options.url = ServiceB.makeUrl("item/#{itemName}")
$http _.defaults(options, defaults)
getVarsets: (options = {}) ->
options.method = "GET"
options.url = ServiceB.makeUrl("items")
$http _.defaults(options, defaults)
getModelsForVarset: (itemName, options = {}) ->
options.method = "GET"
options.url = ServiceB.makeUrl("item/#{itemName}/prices")
$http _.defaults(options, defaults)
])
Service B:
'use strict'
angular.module('services')
.service 'ServiceB', [ ->
# Just return the string
# This service builds the real URL, but I've removed this
makeUrl: (Url) ->
"#{Url}"
]
so are you saying that you know how to do this with $provide/Jasmine spies and are looking for alternatives? I've mostly just used the $provide/spy method for mocking and it's worked out really well for me so far.
something like:
beforeEach(function() {
// set up a default value for your mock
bMock = {
makeUrl: jasmine.createSpy('makeUrl() mock').andReturn('http://www....')
}
// use the $provide service to replace ServiceB
// with your mock
module('services', function($provide) {
$provide.value('ServiceB', bMock);
});
});
it('should do what its supposed to do', function() {
// test...
});
then, if you want to use $httpBackend to mock the http requests in service A, you just need to use the $injector service to grab $httpBackend, then call .when(...) on it to set things up, a la http://docs.angularjs.org/api/ngMock.$httpBackend
I would like to know what's the best way to run specs2 tests on a PlayFramework module and be able to simulate it running.
My module contains some routes in a file named mymodule.routes
In my apps I integrate them by adding the following line in my routes file
-> /mymodule mymodule.Routes
This is the test from my module I try to run but returns a 404 error :
"test myroute" in {
running(FakeApplication()) {
await(WS.url("http://localhost:9000/mymodule/myroute").get).status must equalTo(OK)
}
}
FakeApplication does not really lunch a web process, so you cannot test using http access to localhost.
You have three options:
Testing the controller directly
Testing the router
Testing the whole app.
Testing the controller is done by directly calling your controller and checking the result, as suggested in play documentation, and providing a FakeRequest()
val result = controllers.Application.index("Bob")(FakeRequest())
Testing the router is done by calling routeAndCall with a FakeRequest argument, specifying the relative path:
val Some(result) = routeAndCall(FakeRequest(GET, "/Bob"))
Eventually, if you want to test your whole application, you need to start a TestServer:
"run in a server" in {
running(TestServer(3333)) {
await(WS.url("http://localhost:3333").get).status must equalTo(OK)
}
}
Your question says: "What is the best option?". The answer is: there is nothing such as a best option, there are different way of testing for different purpose. You should pick up the testing strategy which better fits your requirement. In this case, since you want to test the router, I suggest you try approach n.2