I try to migrate from Java 8 to 11 and get an error in my test class that I don't understand.
My failing (groovy) test is:
#SpringJUnitConfig
class TestSpringBeanScopeChecker {
#Autowired
ApplicationContext ctx
#Test
void testSingletonFail() {
Assertions.assertThrows(IllegalStateException.class) {
SpringBeanScopeChecker.check(ctx, DummyPrototype.class, BeanDefinition.SCOPE_SINGLETON)
}
}
}
The SpringBeanScopeChecker:
public class SpringBeanScopeChecker {
private SpringBeanScopeChecker() {}
public static void check(ApplicationContext ctx, Class<?> type, String scope)
throws IllegalStateException {
AbstractApplicationContext actx = (ctx instanceof AbstractApplicationContext) ?
((AbstractApplicationContext) ctx) :
new StaticApplicationContext(ctx);
ConfigurableListableBeanFactory factory = actx.getBeanFactory();
for (String key : ctx.getBeanNamesForType(type)) {
BeanDefinition definition = factory.getMergedBeanDefinition(key);
if (!scope.equals(definition.getScope())) {
throw new IllegalStateException(
"Every spring bean "
+ "must be request scoped in the bean configuration. The current scope is: "
+ definition.getScope());
}
}
}
}
So for the test I'm expecting a IllegalArgumentException. And this is working fine with Java8.
When I switch to Java11 and execute the test I get this error:
[ERROR] testSingletonFail Time elapsed: 0.009 s <<< FAILURE!
org.opentest4j.AssertionFailedError: Unexpected exception type thrown
==> expected: <java.lang.IllegalStateException> but was: <java.lang.AbstractMethodError>
at TestSpringBeanScopeChecker.testSingletonFail(TestSpringBeanScopeChecker.groovy:22)
Caused by: java.lang.AbstractMethodError: Receiver class
TestSpringBeanScopeChecker does not define or inherit an
implementation of the resolved method 'abstract java.lang.Object
getProperty(java.lang.String)' of interface groovy.lang.GroovyObject.
at TestSpringBeanScopeChecker.testSingletonFail(TestSpringBeanScopeChecker.groovy:22)
In case someone else has the same problem I write down the solution for this.
The problem was misconfiguration of the groovy-eclipse-compiler and groovy-eclipse-batch.
My groovy version is managed by spring-boot and I didn't update the groovy-eclipse-batch according to the groovy.version from the spring-boot pom.
According to this issue on github:
You have to compile with groovy-eclipse-batch and groovy runtime in the same version. groovy-eclipse-batch and groovy runtime should be matched up. E.g. batch 2.5.10-0x and runtime 2.5.10 or batch 3.0.1-0x and runtime 3.0.1.
Related
I'm getting this NoClassDefFoundError during run time (Run test via Intellij or via gradlew test)
Here is my simple test (new to Kotlin and Kotest)
class AuthenticationValidatorServiceTest : StringSpec({
val userRepository = mockk<UserRepository>()
val userTypeRepository = mockk<UserTypeRepository>()
val accessTokenRepository = mockk<AccessTokenRepository>()
lateinit var service: AuthenticationValidatorService
beforeTest {
service = AuthenticationValidatorService(userRepository, userTypeRepository, accessTokenRepository)
}
"Should throw ResourceNotFoundException" {
shouldThrow<ResourceNotFoundException> {
val userId = UUID.randomUUID()
every { userRepository.findById(userId) } returns Optional.empty()
service.validateUser(userId)
}
}
})
Is there something that I miss setting up on my gradle file?
I just added the dependencies that this
tasks.withType(Test) {
useJUnitPlatform()
}
Getting these errors
> Task :test
WARNING: ExecutionInvokerPatcher failed: java.lang.ClassNotFoundException: org.junit.jupiter.engine.descriptor.ClassTestDescriptor
Expected exception lock.http.exception.ResourceNotFoundException but a NoClassDefFoundError was thrown instead.
java.lang.AssertionError: Expected exception lock.http.exception.ResourceNotFoundException but a NoClassDefFoundError was thrown instead.
at lock.http.service.AuthenticationValidatorServiceTest$1$2.invokeSuspend(AuthenticationValidatorServiceTest.kt:54)
at lock.http.service.AuthenticationValidatorServiceTest$1$2.invoke(AuthenticationValidatorServiceTest.kt)
at lock.http.service.AuthenticationValidatorServiceTest$1$2.invoke(AuthenticationValidatorServiceTest.kt)
at io.kotest.core.spec.style.scopes.StringSpecRootContext$invoke$1.invokeSuspend(StringSpecRootContext.kt:66)
at io.kotest.core.spec.style.scopes.StringSpecRootContext$invoke$1.invoke(StringSpecRootContext.kt)
at io.kotest.core.spec.style.scopes.StringSpecRootContext$invoke$1.invoke(StringSpecRootContext.kt)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invokeSuspend(executions.kt:13)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invoke(executions.kt)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invoke(executions.kt)
at io.kotest.core.internal.ExecutionsKt.wrapTestWithGlobalAssert(executions.kt:39)
at io.kotest.core.internal.ExecutionsKt.access$wrapTestWithGlobalAssert(executions.kt:1)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invokeSuspend(executions.kt:12)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invoke(executions.kt)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invoke(executions.kt)
at io.kotest.core.internal.ExecutionsKt$wrapTestWithAssertionModeCheck$2.invokeSuspend(executions.kt:25)
at io.kotest.core.internal.ExecutionsKt$wrapTestWithAssertionModeCheck$2.invoke(executions.kt)
at io.kotest.core.internal.ExecutionsKt$wrapTestWithAssertionModeCheck$2.invoke(executions.kt)
at io.kotest.core.internal.AssertionsCheckKt.executeWithAssertionsCheck(assertionsCheck.kt:25)
at io.kotest.core.internal.ExecutionsKt.wrapTestWithAssertionModeCheck(executions.kt:24)
at io.kotest.core.internal.ExecutionsKt.executeWithBehaviours(executions.kt:11)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invokeSuspend(TestCaseExecutor.kt:268)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invoke(TestCaseExecutor.kt)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invoke(TestCaseExecutor.kt)
I'm new with all of that, so the answer should be obvious but I can't get it by myself :op
I'm working on a simple Spring Boot application and I'm "trying" to set up some JUnit test.
In my controller I've this code :
#Controller
public class UserController {
#Autowired
private OrderInfoService orderInfoService;
#RequestMapping(value = "/single", method = RequestMethod.GET)
public ResponseEntity<List<OrderInfo>> orderinfo() {
List<OrderInfo> orderInfo = orderInfoService.getOrderInfo("ca1121a");
System.out.println("Created output string :" + orderInfo.toString());
return new ResponseEntity<List<OrderInfo>>(orderInfo, HttpStatus.OK);
}
}
This is only displaying a test page at "/single". The content of "orderInfo" appear both in the command line and on my web page. Good!
Now I'm trying to setup a JUnit test like this :
public class OrderInfoServiceImplTest {
// Call class under test
private OrderInfoService orderInfoService;
#Test
public void testGetOrderInfo() {
System.out.println("Test - getOrderInfo");
String res = "[OrderInfo :typeNameca1121a - retroFit ]" ;
List<OrderInfo> orderInfo = orderInfoService.getOrderInfo("ca1121a");
System.out.println("Created output orderInfo");
System.out.println("\t" + orderInfo.size());
Assert.assertEquals(res, orderInfo.get(0).toString());
}
}
This give me a null pointer exception :
[INFO] Running OrderInfoServiceImplTest Test - getOrderInfo [ERROR]
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.178
s <<< FAILURE! - in OrderInfoServiceImplTest
[ERROR]
testGetOrderInfo(OrderInfoServiceImplTest)
Time elapsed: 0.115 s <<< ERROR! java.lang.NullPointerException
at com.devglan.service.impl.OrderInfoServiceImplTest.testGetOrderInfo(OrderInfoServiceImplTest.java:23)
I don't understand why my object is well defined in the controller but not in the test, I use exactly the same command. Does it related to the #autowired in the controller (which I have to say I don't understand yet)?
Any help would be appreciate.
Thank you
Some annotations, which make your test case class be run under the control of spring test framework and your object under test is auto-wired to your test case class,are missed.
As for your example , the following code will work.
#RunWith(SpringRunner.class)
#SpringBootTest
public class OrderInfoServiceImplTest {
// autowire class under test
#Autowired
private OrderInfoService orderInfoService;
#Test
public void testGetOrderInfo() {
System.out.println("Test - getOrderInfo");
String res = "[OrderInfo :typeNameca1121a - retroFit ]" ;
List<OrderInfo> orderInfo = orderInfoService.getOrderInfo("ca1121a");
System.out.println("Created output orderInfo");
System.out.println("\t" + orderInfo.size());
Assert.assertEquals(res, orderInfo.get(0).toString());
}
}
I am creating an instance of Predicate using a provider.
#Provides
#Singleton
#Named("RecordFilters")
public Predicate<ImmutablePair<AbstractRecord, StreamRecord>> getAllFilters() {
BackfillDataFilter backfillDataFilter = new BackfillDataFilter();
DummyUpdateFilter dummyUpdateFilter = new DummyUpdateFilter();
return input -> dummyUpdateFilter.test(input) && backfillDataFilter.test(input);
}
When i am trying to get its instance using injector.getInstance(Predicate.class) or injector.getInstance(Key.get(Predicate.class, Names.Named("RecordFilters"))
I am getting an exception.
com.google.inject.ConfigurationException: Guice configuration errors:
No implementation for java.util.function.Predicate was bound.
while locating java.util.function.Predicate
Please suggest.
Try as described in this answer:
injector.getInstance(Key.get(new TypeLiteral<Predicate<ImmutablePair<AbstractRecord, StreamRecord>>>(){})
Issue : When running integration tests from maven (mvn verify) the spring application context is not initialized properly, it doesn't take in consideration my custom ApplicationContextInitializer class.
Test Class :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {MainApplication.class}, initializers = CustomContextInitializer.class)
#WebIntegrationTest
public class ApplicationIT {
// Running a SOAPUI suite as a JUnit Test
#Test
public void TestGateway() throws Exception {
SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
runner.setProjectFile("../gateway/src/test/resources/soapui/gateway-soapui.xml");
runner.run();
}
}
MainApplication class :
#Configuration
#ComponentScan(basePackages = {
// different packages here (not relevant)
})
#EnableAutoConfiguration
public class MainApplication {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(MainApplication.class)
.initializers(new CustomContextInitializer())
.run(args);
}
}
CustomContextInitiliazer class (for adding custom .properties files to the spring environment application context) :
public class CustomContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment env = applicationContext.getEnvironment();
try {
Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath*:/*.properties");
for (Resource re : res) {
env.getPropertySources().addFirst(new ResourcePropertySource(re));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Results :
1) Everything works on when I start and run the application (either from IDE or by invoking mvn exec).
2) Integration tests run ok when started from IDE.
3) Integration tests throw error when invoked via maven verify because the custom properties files are not loaded into spring context environment. The result is the same as if I wouldn't have written initializers = CustomContextInitializer.class in the test class and tried to run the tests from IDE.
I think your code is correct, but your .properties files may be at the wrong place. Make sure they are under <project>/src/main/resources or that you have configured a custom resource folder in maven. If they reside under <project>/src/main/java they will not be part of the classpath as far as maven is concerned.
I decided to try the rest-driver library for my unit tests.
I have the following code:
public class RemoteSessionAccountantTest {
#Rule
public ClientDriverRule driver = new ClientDriverRule();
// ...
#Test
public void singleUserSession() throws IOException, JSONException {
driver.addExpectation(
onRequestTo("http://myTestUrl/anyUsername").withMethod(Method.GET),
giveResponse("[{\"contractCode\":\"1234\"}]", "application/json"));
// ...
}
// ...
}
But I'm not even reaching the test case because instantiating the ClientDriverRule results in an error:
com.github.restdriver.clientdriver.exception.ClientDriverSetupException:
Error starting jetty on port 0
...
Caused by: java.lang.IllegalStateException: Local port was not set
Now I've tried setting a specific port, but it didn't help.
I have jetty v9.3.0 (also tried versions 8.x.x, 9.1.x, 9.2.x with no luck)
rest-client-driver version 1.1.42
The problem seems to be coming from jetty, but I cannot figure out what exactly.