Spring MVC 5 ResultMatcher jsonPath null value - spring

After upgrading my rest service from Spring Boot 1.5.10 to 2.0.0 I encountered my tests failing which passed before.
Following Scenario:
import org.mockito.internal.matchers.Null;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
...
.andExpect(jsonPath("img").value(Null.NULL))
Fails now in Spring MVC 5 with following message:
java.lang.AssertionError: JSON path "img"
Expected :isNull()
Actual :null
What is the correct way in Spring MVC 5 to assert that the value of the jsonPath is null?

Answering my own question as I found the solution by myself.
You have to use the correct Matcher, in my case org.hamcrest.core.IsNull
So I had to change to
import org.hamcrest.core.IsNull;
...
andExpect(jsonPath("img").value(IsNull.nullValue()))

April 2022, Hamcrest 2.2
nullValue() is a standalone static method importable by org.hamcrest.CoreMatchers.nullValue.
So, updated solution resolves to
static import org.hamcrest.core.nullValue;
...
andExpect(jsonPath("img").value(nullValue()))

You can use content().srtring(Matcher matcher) and then use IsEmptyString matcher
result.andDo(print())
.andExpect(status().isNoContent())
.andExpect(content().string(IsEmptyString.isEmptyOrNullString()));

Related

I can't import the containsString CoreMatcher from hamcrest

I'm trying to do the following:
import static org.hamcrest.CoreMatchers.containsString
assertThat(myvar, containsString("string to check"))
Here are my dependencies. I need to support junit 4 and junit 5
testCompile('org.mockito:mockito-all:+')
testCompile('org.mockito:mockito-inline:+')
// use junpiter
testImplementation(platform('org.junit:junit-bom:+'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.junit.jupiter:junit-jupiter-params')
// AND junit 4 because I use a test framework that has a hard dependency on junit 4
testImplementation("junit:junit:4.13")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.7.2")
// Trying to pull in latest hamcrest
testImplementation('org.hamcrest:hamcrest:2.2')
The problem is in my class when I to import static org.hamcrest.CoreMatchers.containsString It appears to be using hamcrest 1.3 which does not have "containsString". Is it using 1.3 because junit 4 depends on this version of hamcrest?
Is what I'm trying to do impossible because I'm pulling in both junit 4 and jupiter?
EDIT
In my editor it says it does not exist:
Using my IDE I can read its docs on my localhost: (http://localhost:63342/..../hamcrest-core-1.3-javadoc.jar/org/hamcrest/CoreMatchers.html)
When trying to run it I get this error
No signature of method: src.myproject.MyClassTest.containsString() is applicable for argument types: (String) values: [string to check]
groovy.lang.MissingMethodException: No signature of method: src.myproject.MyClassTest.containsString() ....
Per comments I can see now it looks like its using CoreMatchers from mockito for some reason:
EDIT Solution
Per comments the issue was that CoreMatchers was coming from mockito. I have removed mockito as a dependency and deleted its jars and that fixed it.
But I still don't understand how/why this was happening. I hope a proper answer to my question will include an explanation of why CoreMatchers was being fetched from the wrong place.

Cucumber with Spring Config doesnt work, can't run tests: io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class

im trying to setup a cucumber with spring project to use autowiring and spring config options (application.yml). Now that i created a runner class to pass parameters from outside executing runs on following exception:
Weird is, i have a class exactly with the proposed annotations, so i guess it's not found and something on the project structure is off, but i don't get what exactly.
Here is my project structure:
src.main.java.package.config.SpringConfig.java
src.main.java.package.steps.StepsSpringConfig.java
src.test.java.package.runner.CucumberRunner.java
SpringConfig.java
#ComponentScan("package")
#EnableConfigurationProperties{PropertyClasses}
StepsSpringConfig.java
#SpringBootTest(classes = SpringConfig.class)
#CucumberContextConfiguration
All Step classes extend from this class
CucumberRunner.java
#RunWith(Cucumber.class)
#CucumberOptions(steps = path/to/features, glue = {src.package.steps, src.package.config})
In my JUnit RunConfig I use this runner class
When i run i get the error on the screenshot above. What am i missing?
Im using the latest version of IntelliJ (2021.2.2)
Im using Spring 2.3.12 and cucumber-junit 6.8.0
Ok im dumb, the solution is found here: Cucumber options annotation
i specified the glue path like "src.main.java.package.steps" but it needs to be just "package.steps" and it works fine

Micronaut declarative REST client throws an error - #Introduction method interceptor missing

When I autowire the client interface for my Micronaut declarative client, I get this error:
Caused by: java.lang.IllegalStateException: At least one #Introduction method interceptor required, but missing. Check if your #Introduction stereotype annotation is marked with #Retention(RUNTIME) and #Type(..) with the interceptor type. Otherwise do not load #Introduction beans if their interceptor definitions are missing!
at io.micronaut.aop.chain.InterceptorChain.resolveIntroductionInterceptors(InterceptorChain.java:194)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1494)
What's the proper way to fix it?
Details
I have an established Grails application that I recently upgraded from 3.x to 4.0.1.
This app has a service which does several REST calls in parallel, and I am trying to add a new REST call that uses the new Micronaut HTTP declarative client.
I added the client library to dependencies in build.gradle:
compile "io.micronaut:micronaut-http-client"
My client interface looks like this (in src/main/groovy):
package com.mycompany.xyz.rest
import com.mycompany.xyz.rest.myendpoint.Results
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Header
import io.micronaut.http.client.annotation.Client
#Client('xyzRest')
#Header(name = 'myauthkey', value = '${myAuthKey}')
interface XyzRestClient {
#Get('/myendpoint')
Results myendpoint(String param1, String param2)
}
package com.mycompany.xyz.rest.myendpoint
import com.mycompany.xyz.rest.myendpoint.DataItem
import groovy.transform.CompileStatic
#CompileStatic
interface Results extends List<DataItem> {
}
I configured the URL in application.yml:
environments:
development:
micronaut:
http:
services:
xyzRest:
urls:
- http://xyz.mycompany.com/rest/v1
The message about #Introduction makes me think that Micronaut is not doing the process of compiling the declarative client. Is there some
What else am I missing?
Update:
I tried changing the build.gradle dependency to implementation as shown in the Micronaut docs, insteadl of compile, as shown in the Grails docs. No dice.
Update 2:
I found that the constructor for HttpClientIntroductionAdvice is never invoked during startup. I don't know why it's not being included in my project. IntelliJ shows micronaut-http-client:1.1.4 in external libraries, and it's set to compile scope.
A gradlew clean seems to have fixed the issue.
I tried to work backwards and duplicate the problem for posterity's sake, but so far I have not been able to.

Expose GraphqlExceptions using spring boot starter

When using the Spring Boot starter for graphql, all of the exceptions thrown while data fetching appear in the output console as "Internal Server Error(s) while executing query" I would like the just the e.message() string of the GraphQLException I throw to come out of the "message" part of the error field in Graphql so that the front end of this API can see what went wrong.
I've googled this to no avail. Most people expose the errors by editing the Servlet, but since I'm using the Spring Boot starter I cannot do this easily. I know that the graphql-servlet used by starter has a class called DefaultGraphQLErrorHandler found here but I do not know how to override or change it or just somehow get those errors to display.
I tried overriding the SimpleDataFetcherExceptionHandler in graphql, creating a CustomException that overrides GraphQlException but neither worked, the SimpleDataFetcherExceptionHandler implementation was never called during a debug.
I only ever see this:
Thanks
So I figured this out. I had to provide a custom implementation of a GraphQLErrorHandler and add it to the list of beans by marking as a #Component. I then overrided the processErrors() function in the error handler. When marked as a component, this bean was autowired into the graphql serverlet configurator in the graphql spring boot starter package, replacing the default one.
the CustomGraphQlErrorHandler I added is seen below:
import graphql.GraphQLError
import graphql.servlet.GenericGraphQLError
import graphql.servlet.GraphQLErrorHandler
import org.springframework.stereotype.Component
#Component
class CustomGraphQlErrorHandler: GraphQLErrorHandler {
override fun processErrors(errors: MutableList<GraphQLError>?): MutableList<GraphQLError> {
val errorList = mutableListOf<GraphQLError>()
for(error in errors!!){
errorList.add(GenericGraphQLError(error.message))
}
return errorList
}
}
the output looks like this now:
SimpleDataFetcherExceptionHandler implementation will be called when you have graphql.servlet.exception-handlers-enabled=true in application.properties
Great solution works like a charm.
A more compact way of writing it in kotlin would look like this:
#Component
class CustomGraphQlErrorHandler : GraphQLErrorHandler {
override fun processErrors(errors: MutableList<GraphQLError>?) =
errors?.map { GenericGraphQLError(it.message) }?.toMutableList() ?: mutableListOf()
}
I really like the functional style of this

spring 3.x issue of no such method error

Hi i am using spring framework and while executing annotationbased test case i am getting error can any one have idea about which jar dependancy(maven artifact) file do i need to add in my pom.xml ?
org.springframework.transaction.interceptor.TransactionAttribute.getQualifier() no such method error
Looks like you have two incompatible jars.
Check that: spring-tx and spring-test is of the same version (3.0.x).
If this does not help. Place a break point at TransactionalTestExecutionListener and check that the concreate class that implements TransactionAttribute is of correct version too.

Resources