Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StubServiceBuilder needs an unprocessed(UnProcessedHandler handler) method. #47

Open
paul-hammant opened this issue Feb 8, 2017 · 10 comments

Comments

@paul-hammant
Copy link

I might be mocking my service endpoints, but wanting my HTML, JS, CSS, PNG to be statically served.

service(domain).unprocessed(myUnProcessedHandler)

UnProcessedHandler would have a method:

Response handleUnprocessed(Request req) {
}

You should be able to fix response codes, mimetypes, set bodies in there.
Also, a Response.DO_ACTUAL_PROXY_HTTP_CALL would be nice (for my HTML etc need).

@tommysitu
Copy link
Member

@paul-hammant, did you mean the StubServiceBuilder should simulate response with static files? Could you elaborate a bit more on the use case please?

@ph-ms
Copy link

ph-ms commented Feb 8, 2017

I might unprocessed() to be able to serve static content, yes.

Others might want a callback API so they can participate programmatically in situations where an endpoint wasn't mocked. I.e. do deterministic code in that situation, rather than declared-upfront request/response pairings.

@mogronalol
Copy link
Contributor

mogronalol commented Feb 8, 2017

@paul-hammant I think there are two problems here.

The first one I would do something more like:

service("www.my-test.com")
   .post("/api/bookings").body("{\"flightId\": \"1\"}")
   .willReturn(created("http://localhost/api/bookings/1"))
   .unprocessed()
   .willReturn(...)

It would still be using a matcher internally, it's just that it matches on the host and ignores all the other fields. It would take lower level of precedence over stronger matches (By this I mean, if there is a match on more than one field, that's the response it should chose over a match on a single field).

For the second one, depending on what you are trying to do, there could be a few solutions.

  1. You can configure the JVM to proxy to exclude www.static.com and include www.service.com (this assumes your service is on different domain to static content). This would be an easy way of not proxying a service under test, but proxying it's external dependency.
  2. Rather than using the JVM proxy, we can introduce the functionality via Hoverfly using destination filters
  3. We could introduce the http equivalent of Mockito Spy or partial mock. The idea would be that if there is a match it would return it, otherwise call out to the real service (This would work across domains)

Any of these settings would be global.

Judging from what you've said, I think number 3 would be most suitable. I'm curious if that would be a sufficient alternative to your per matcher Response.DO_ACTUAL_PROXY_HTTP_CALL.

@ph-ms
Copy link

ph-ms commented Feb 8, 2017

For the first one will the args passed in to .willReturn(...) have an ability to determine the URL/verb sought?

I was imagining that the unprocessed(..) would not have a corresponding willReturn(..)

A Mockito-style spy would be great.

@mogronalol
Copy link
Contributor

mogronalol commented Feb 8, 2017

Hm, I see what you mean. So when it doesn't match on anything other than the host, you'd want some sort of logic to used to generate a response. Could that work as different matchers though? Something like:

service("www.my-test.com")
   .post("/api/bookings").body("{\"flightId\": \"1\"}")
   .willReturn(created("http://localhost/api/bookings/1"))
   .unprocessedGet() // Matches on any GET to www.my-test.com with no stronger match
   .willReturn(notFound())
   .unprocessedPost() // Matches on any POST to www.my-test.com with no stronger match
   .willReturn(internalServerError())
   .unprocessed() // Matches on any METHOD to www.my-test.com with no stronger match
   .willReturn(internalServerError())

@tommysitu
Copy link
Member

I think the following might be more clear:

service("www.my-test.com")
   .post("/api/bookings").body("{\"flightId\": \"1\"}")
   .willReturn(created("http://localhost/api/bookings/1"))
   
   .unMatched(request().get("/html/*")) // Matches on any GET to www.my-test.com/html/* with no stronger match
   .willReturn(notFound())
   
   .unMatched(request().post()) // Matches on any POST to www.my-test.com with no stronger match
   .willReturn(internalServerError())
   
   .unMatched() // Matches on any METHOD to www.my-test.com with no stronger match
   .willReturn(internalServerError())

Enable destination filtering to allow call to real service is already captured in issue #19

Have a SPY mode is a good idea.

@ph-ms
Copy link

ph-ms commented Feb 8, 2017

The dynamic case needs to be made

.unMatched(request().get("*.html")).willReturn(letMeGetThatForYou())

  • how does letMeGetThatForYou() know what URL was being sought in order to (say) .getReasourceAsStream(resourceName) it?

Like so:
.unMatched(myCapturingMatcher()).willReturn(letMeGetThatForYouUsingSomethingCapturedOnShockHorrorThreadLocal())

@tommysitu
Copy link
Member

The DSL is just another way of creating a static simulation file to preload into Hoverfly. It is not compiled dynamically to generate a response.

You are probably looking for the [Synthesize Mode] (http://hoverfly.io/en/latest/pages/keyconcepts/modes/synthesize.html)

It would require the support of Middleware #7.

@mogronalol
Copy link
Contributor

@paul-hammant Spy behaviour will be put in Hoverfly first, here is an issue.

@mogronalol
Copy link
Contributor

@ph-ms In reference to unmatched, you can't actually add any logic like this into Hoverfly Java, it would have to be done using middleware, which is yet to be supported. I can think of another workaround to get it to work, but it feels quite hacky.

Could you give me an example of your specific use case please? As in, why do you need to do:

.unMatched(request().get("*.html")).willReturn(needToKnowUrl())

Instead of

service("www.url-i-need-to-know").unmatched(...)

I'm trying to get my head around a situation where you wouldn't want to do everything statically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants