Spring Contract ignore test with message - spring-cloud-contract

I have the following code:
Contract.make {
ignoreTestBaseOnACondition() ? ignored() : ""
description "e"
request {
method 'POST'
url '/api/login'
headers {
contentType("application/json")
}
body($(execute("aMethod()")))
}
response {
status 200
headers {
contentType("application/json")
}
}
}
and it generates:
#Test
#Ignore
public void someName(){}
Sonar complains asking for a description on the ignore method, something like:
#Test
**#Ignore("See Ticket #1234")**
public void testDoTheThing() {}
Is there any way to achieve this with spring contract?

Related

Spring Cloud Contract generated tests fails on empty responses from producer

I am trying to implement Spring Cloud Contract to my project. I am following instructions from this baeldung article:
https://www.baeldung.com/spring-cloud-contract
Dependencies are added
Plugin is configured
Producer contract is defined
BaseTest is defined
Unfortunately my generated tests fails because the response (jsonBody) is "empty"
Here's a few pieces of the setup:
BaseContractTest =>
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
#AutoConfigureMessageVerifier
#DirtiesContext
#AutoConfigureStubRunner(ids = "com.example:producer-service:+:stubs:8080",
stubsMode = StubRunnerProperties.StubsMode.LOCAL)
public class BaseContractTest
{
#Autowired
private WebApplicationContext webApplicationContext;
#BeforeEach
void setUp()
{
final DefaultMockMvcBuilder defaultMockMvcBuilder =
MockMvcBuilders.webAppContextSetup(webApplicationContext);
defaultMockMvcBuilder.apply(
springSecurity((request, response, chain) -> chain.doFilter(request, response)));
RestAssuredMockMvc.mockMvc(defaultMockMvcBuilder.build());
}
contract =>
Contract.make {
description "GetCustomer should return a Customer"
request {
method GET()
url value(consumer(regex('/producer-service/v1/customer/ID-\\d*-\\d*')), producer("/producer-service/customer/ID-132456-9876"))
}
response {
status OK()
body(
id: "ID-132456-9876", name: "exampleName"
)
headers {
contentType(applicationJson())
}
}
}
wiremocks mapping are properly generated (omitted for brevity)
Generated ContractTest =>
public class ContractVerifierTest extends BaseContractTest {
#Test
public void validate_shouldReturnACustomer() throws Exception {
// given:
MockMvcRequestSpecification request = given();
// when:
ResponseOptions response = given().spec(request)
.get("/producer-service/v1/ID-132456-9876");
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).matches("application/json.*");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).field("['id']").isEqualTo("ID-132456-9876");
assertThatJson(parsedJson).field("['name']").isEqualTo("exampleName");
}
}
when the test runs, it fails with this error:
validate_shouldReturnACustomer Time elapsed: 0.731 s <<< FAILURE!
java.lang.AssertionError:
Expecting actual not to be null
at com.example.contracts.ContractVerifierTest.validate_shouldReturnACustomer(ContractVerifierTest.java:31)
When I look up the corresponding error line, it fails on =>
assertThat(response.header("Content-Type")).matches("application/json.*");
I am a bit clueless at this point.
I tried to use the MockStandaloneApp tied to the controller (as per the link to baeldung) but that did not help.
Note that the service returns a Mono<Customer> not an actual Customer, if that changes anything.

How can I make and ASP action filter return a status code of 201?

I have this action filter:
public class ValidateModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Result = new BadRequestObjectResult(actionContext.ModelState);
}
}
}
But my front-end code sees this in the same way that it sees a lost connection to the server.
How can I make it so that instead of returning a BadRequestObjectResult that I return a status code of 201 ?
You can throw an exception like this:
if (!actionContext.ModelState.IsValid)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Created));
}
This will immediately stop the request and return a 201 to the client.

OWIN Stop Processing Based on Condition?

I have the below code in my OWIN Startup class:
myiapbuilder.Map("/something/something", doit =>
{
doit.Use<pipepart1>();
doit.Use<pipepart2>();
doit.Use<piprpart3>();
});
If a condition occurs that I don't like in pipepart1, I would like to write a custom text/plain response to the caller within that Middleware, and do not fire pipepart2 or pipepart3. The BranchingPipelines sample on CodePlex shows lots of stuff, but not that.
Is it possible to short-circut a flow or otherwise stop OWIN processing of Middleware based on an earlier Middleware evaluation?
if you plan to respond directly to the client from pipepart1, then you could avoid calling other middlewares in the pipeline. Following is an example. Is this something you had in mind?
Here based on some condition (in my case if querystring has a particular key), I decide to either respond directly to the client or call onto next middleware.
appBuilder.Map("/something/something", doit =>
{
doit.Use<Pipepart1>();
doit.Use<Pipepart2>();
});
public class Pipepart1 : OwinMiddleware
{
public Pipepart1(OwinMiddleware next) : base(next) { }
public override Task Invoke(IOwinContext context)
{
if (context.Request.Uri.Query.Contains("shortcircuit"))
{
return context.Response.WriteAsync("Hello from Pipepart1");
}
return Next.Invoke(context);
}
}
public class Pipepart2 : OwinMiddleware
{
public Pipepart2(OwinMiddleware next) : base(next) { }
public override Task Invoke(IOwinContext context)
{
return context.Response.WriteAsync("Hello from Pipepart2");
}
}

Response.AsJson doen't work when calling it from a function in NancyFx

The extension methods:
Response.AsJson
Response.AsXml
works fine when calling it from the constractor like:
public class TweetModule : NancyModule
{
public TweetModule()
: base("/")
{
Post["/{action}.json/"] = parameters =>
{
return Reponse.Asjson(new {output:parameters.action}); // OK
}
}
}
But when I call it from a function like this:
public class TweetModule : NancyModule
{
public TweetModule()
: base("/")
{
Post["/{action}.{format}/"] = parameters =>
{
return GetResponse( parameters.action,parameters.format); // Error
}
}
public Response GetResponse(string action,string format)
{
if (format == "json")
return Response.AsJson(new {output:action}); // error
else
return Response.AsXml(new {output:action}); // error
}
}
I get this exception:
<>f__AnonymousType0`1[System.String] cannot be serialized because it
does not have a parameterless constructor.
any advice?
Na that works just fine. The problem is that your captured parameter is called {fortmat} and you then pass along parameters.format which is never captured due to the typo
And I have to point out that your code won't even compile since function is not a valid keyword in C#, I just assumed that you actual meant it to say public instead.
Hope this helps

Sending Generic Messages

public class Foo<T> where T: Entity
{}
public class Foo1
: Foo<Telephone>
{
}
public class Foo2
: Foo<Home>
{
}
How do I send Foo1 to Foo2? I realize that the message is typed, and hence messages of the same type of recieved - but I need to message between the derived classes...
An example would be very much appreciated.
An alternative is to create your own class that contains the payload you wish to deliver (Foo1 or simply object). Then in Foo2, register to receive messages of the type of the class you just created.
This link explains how with a very easy to understand example.
MVVM Light Toolkit Soup To Nuts 3 - Jesse Liberty
the messaging in mvvmlight is in theory supposed to be fire and forget...the sender doesnt care who gets the message and the receiver doesnt care who sends the message, so long as its the right type that its listening for.
I have found through much trial and error that its much easier to craft your own messages than use the default provided by mvvm-light, they are a good starting point, but sometimes you will just findyourself jumping through hoops..
public class ExceptionMessage : GalaSoft.MvvmLight.Messaging.GenericMessage<System.Exception>
{
public ExceptionMessage(System.Exception content) : base(content) { }
public ExceptionMessage(object sender, System.Exception content) : base(sender, content) { }
public ExceptionMessage(object sender, object target, System.Exception content) : base(sender, target, content) { }
}
Receiver code:
Messenger.Default.Register<Core.Messaging.ExceptionMessage>(this, ex => ShowExceptionMessage(ex));
Sender Code:
public void LogException(Exception content)
{
_messenger.Send<Core.Messaging.ExceptionMessage>(new ExceptionMessage(content));
//GetBw().RunWorkerAsync(content);
WriteToDatabaseLog(content);
}
and yes this does break the suggestion in my first sentence, but in theory I could have several vms or view listening for exception messages.
Maybe another example to help you out... i hate the whole foo thing...its always confuses me...
This is in my core module:
public class SaveNotification<T> : GalaSoft.MvvmLight.Messaging.NotificationMessage<T> where T : GalaSoft.MvvmLight.ViewModelBase
{
public SaveNotification(T content, string notification) : base(content, notification) { }
public SaveNotification(object sender, T content, string notification) : base(sender, content, notification) { }
public SaveNotification(object sender, object target, T content, string notification) : base(sender, target, content, notification) { }
}
here is how I used it in my vm:
public void OnSubmitChanges(SubmitOperation so)
{
if (so.HasError)
{
Infrastructure.GetService<IExceptionLoggingInterface>().LogException(this, so.Error);
}
else
{
//Save Responses
_messenger.Send<Messages.NavigationRequest<SubClasses.URI.PageURI>>(GetNavRequest_HOME());
ClearQuestionaire(true);
_messenger.Send<WavelengthIS.Core.Messaging.SaveNotification<QuestionairreViewModel>>(GetSuccessfulSaveNotification());
}
Wait.End();
}
private WavelengthIS.Core.Messaging.SaveNotification<QuestionairreViewModel> GetSuccessfulSaveNotification()
{
return new WavelengthIS.Core.Messaging.SaveNotification<QuestionairreViewModel>(this, "Save Successfull");
}

Resources