how to check if a service implements an interface in grails - spring

I have an interface "TestInterface" and grails service "TestService" that implements the "TestInterface". But when I test if I have a service that implements the interface like this:
application.serviceClasses?.each { serviceClazz ->
if(serviceClazz instanceof TestInterface) {
println "service name => "+ serviceClazz.name;
}
}
The result is I am not getting anything neither error nor my expectation ( service name => TestService )
I have also tried changing the serviceClazz to serviceClazz.class,serviceClazz.metaClass in the if condition but still not working.
Thank you,

What about:
if (TestInterface.class.isAssignableFrom(serviceClazz)) {
...
}
UPDATE
So I managed to run the actual example using Grails 2.3.11.
class BootStrap {
def grailsApplication
def init = { servletContext ->
grailsApplication.serviceClasses.each { serviceClazz ->
if (TestInterface.isAssignableFrom(serviceClazz.clazz)) {
println serviceClazz
}
}
}
def destroy = {
}
}
As you can see, the important part is clazz in serviceClazz.clazz.
Hope this helps!

Related

Quarkus #CacheResult is not working properly

I am trying to use quarkus-cache by following the appropriate quarkus doc. I have the below code setup
#ApplicationScoped
class MyClass {
public result doSomething() {
String remoteData = getRemoteData(url);
}
#CacheResult(cacheName = "myCacheName")
public String getRemoteData(String url) {
return remoteCall(url);
}
}
Usage
// Grpc impl class
// call to Myclass.doSomething()
Execution is not proceeding further when getRemoteData() is called the first time. Also, not getting any error.
Am I missing something?

Kotest and kotlinx-coroutines-test Integration

I use the Funspec testing style in kotest and I get a coroutineScope injected automatically by the framework as shown below.
class MyTestSpec: FunSpec() {
init {
test("test event loop") {
mySuspendedFunction() // a coroutineScope is already injected by the test framework here
}
}
}
How can I configure the Kotest framework to use an instance of kotlinx.coroutines.test.TestCoroutineScope instead of a kotlinx.coroutines.CoroutineScope in my tests? or is there a reason why this wouldn't make sense?
Since Kotest 5.0, there is built-in support for TestCoroutineDispatcher. See here
Simply:
class MyTest : FunSpec(
{
test("do your thing").config(testCoroutineDispatcher = true) {
}
}
)
Create a test listener like this:
class MainCoroutineListener(
val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
) : TestListener {
override suspend fun beforeSpec(spec: Spec) {
Dispatchers.setMain(testDispatcher)
}
override suspend fun afterSpec(spec: Spec) {
Dispatchers.resetMain()
testDispatcher.cleanupTestCoroutines()
}
}
Then use it in your test like this
class MyTest : FunSpec({
listeners(MainCoroutineListener())
tests...
})

How to configure Selenide remote grid url in Selenium-Jupiter test framework?

I am trying to configure a Selenide driver within the Selenium-Jupiter framework, to use my remote grid url but it keeps ignoring the configuration, and just runs the local installed browser. Here is how I am trying to configure it. Any idea what might be wrong here?
import com.codeborne.selenide.Configuration;
import com.codeborne.selenide.SelenideConfig;
import io.github.bonigarcia.seljup.SelenideConfiguration;
import static com.codeborne.selenide.Browsers.CHROME;
public abstract class ChromeTest extends BaseTest {
#SelenideConfiguration
SelenideConfig selenideConfig = new SelenideConfig();
private String getSeleniumRemote() {
System.getProperty("selenide.remote", "");
}
public ChromeTest() {
if (getSelenideRemote().isEmpty()) {
selenideConfig.proxyEnabled(false)
.browser(CHROME).startMaximized(false)
.browserSize("800x1200").browserPosition("50x60");
} else {
Configuration.timeout = 6000;
Configuration.remote = getSelenideRemote();
selenideConfig.proxyEnabled(false)
.startMaximized(true).browser(CHROME);
}
}
}
I know the regular RemoteWebDriver works and I can get that working but I am hoping to use Selenide in the above example:
Example:
#Test
void testWithRemoteSelenide(#DriverUrl("http://127.1:4444/wd/hub")
#DriverCapabilities("browserName=" + CHROME) SelenideDriver driver)
I can get it to work with the annotation, but the problem is that I need that annotation to be conditional on passing a param to the tests. I want to be able to easily switch using grid or local. Thanks for your help anyone.
Ok, after almost 48 hours an no reponse, I finally figured out the solution. Here it is:
//build.gradle
test {
useJUnitPlatform()
ignoreFailures = false
beforeTest { descriptor ->
logger.lifecycle("Running test: $descriptor.className")
}
systemProperty "env", System.getProperty("env")
def remote = System.getProperty("selenide.remote", "")
if (!remote.isEmpty()) {
systemProperty("selenide.remote", remote)
}
}
Then, in my test base class:
public abstract class ChromeTest extends BaseTest {
#SelenideConfiguration
SelenideConfig selenideConfig = new SelenideConfig();
/**
* This config is equivilant to the documented method:
* Example: test(#DriverUrl("http://127.1:4444/wd/hub")
* #DriverCapabilities("browserName=chrome") SelenideDriver sd)
*/
public ChromeFormTest() {
if (getSelenideRemote().isEmpty()) {
selenideConfig.proxyEnabled(false).proxyHost("http://proxy.domain.com")
.proxyPort(8080)
.browser(CHROME).startMaximized(false)
.browserSize("800x1200").browserPosition("50x60");
} else {
Configuration.timeout = 6000;
Configuration.remote = getSelenideRemote();
selenideConfig.proxyEnabled(false).proxyHost("http://proxy.domain.com")
.proxyPort(8080)
.startMaximized(false).browser(CHROME);
}
}
}
Then, when I execute, it looks like this:
gradle clean test -Denv=sys -Dselenide.remote=http://127.1:4444/wd/hub
--info --tests com.qa.suite.*
And the constructor of each test looks like:
#Test
public void testWhatever(SelenideDriver sd) {

Spring-fu-Kofu: Unable to wire `NamedParameterJdbcTemplate`

I am playing around with Kofu functional Bean DSL. I am using Spring-Data-JDBC with Spring-MVC and trying to autowire NamedParameterJdbcTemplate. However, I am have been receiving this error that no beans found for it while running tests. In a annotation based approach, we don’t have to supply an explicit NamedParameterJdbcTemplate. My sample app here: https://github.com/overfullstack/kofu-mvc-jdbc. And PFB some code snippets from it:
val app = application(WebApplicationType.SERVLET) {
beans {
bean<SampleService>()
bean<UserHandler>()
}
enable(dataConfig)
enable(webConfig)
}
val dataConfig = configuration {
beans {
bean<UserRepository>()
}
listener<ApplicationReadyEvent> {
ref<UserRepository>().init()
}
}
val webConfig = configuration {
webMvc {
port = if (profiles.contains("test")) 8181 else 8080
router {
val handler = ref<UserHandler>()
GET("/", handler::hello)
GET("/api", handler::json)
}
converters {
string()
jackson()
}
}
}
class UserRepository(private val client: NamedParameterJdbcTemplate) {
fun count() =
client.queryForObject("SELECT COUNT(*) FROM users", emptyMap<String, String>(), Int::class.java)
}
open class UserRepositoryTests {
private val dataApp = application(WebApplicationType.NONE) {
enable(dataConfig)
}
private lateinit var context: ConfigurableApplicationContext
#BeforeAll
fun beforeAll() {
context = dataApp.run(profiles = "test")
}
#Test
fun count() {
val repository = context.getBean<UserRepository>()
assertEquals(3, repository.count())
}
#AfterAll
fun afterAll() {
context.close()
}
}
This is the error:
Parameter 0 of constructor in com.sample.UserRepository required a bean of type 'org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate' in your configuration.
Please help, thanks
Apparently Kofu doesn't pick datasource from application.properties file. Everything is meant to be declarative and no implicit derivations. (Basically no Spring magic 🙂). This worked for me:
val dataConfig = configuration {
beans {
bean {
val dataSourceBuilder = DataSourceBuilder.create()
dataSourceBuilder.driverClassName(“org.h2.Driver”)
dataSourceBuilder.url(“jdbc:h2:mem:test”)
dataSourceBuilder.username(“SA”)
dataSourceBuilder.password(“”)
dataSourceBuilder.build()
}
bean<NamedParameterJdbcTemplate>()
bean<UserRepository>()
}
listener<ApplicationReadyEvent> {
ref<UserRepository>().init()
}
}

Using AOP in Grails is not working for service

I use Grails 2.2.3 and type following codes in grails-app/conf/spring/resources.groovy
beans = {
xmlns aop:"http://www.springframework.org/schema/aop"
loggerAspect(com.test.aop.aspect.LoggerAspect)
aop{
config("proxy-target-class": true) {
aspect(id: "beforeService", ref: "loggerAspect") {
before method: "beforeMethod",
pointcut: "execution(* com.test.DemoService.serviceMethod())"
}
aspect(id: "afterService", ref: "loggerAspect") {
after method: "afterMethod",
pointcut: "execution(* com.test.DemoService.serviceMethod())"
}
}
}
}
then, create an aspect class under src/groovy/com/test/aop/aspect
package com.test.aop.aspect
class LoggerAspect {
def beforeMethod(JoinPoint jp){
println '-- Before Method.'
}
def afterMethod(JoinPoint jp){
println '-- After Method.'
}
}
And create a service class under grails-app/services/com/test
package com.test
class DemoService {
def serviceMethod() {
println 'In DemoService.serviceMethod()'
}
}
And create a controller to call service for testing
package com.test
class DemoController {
def index() {
println 'In DemoController.index()'
def demoService = new DemoService()
demoService.serviceMethod()
render 'Hello World'
}
}
Finally, I test the aop through url:
http://myhost:8080/grails-spring-aop/demo/index
and the aop is not invoked. Following is the result:
| Server running. Browse to http://myhost:8080/grails-spring-aop/
In DemoController.index()
In DemoService.serviceMethod()
I add the following line to the service class:
static transactional = false
And, it's still not working for me.
Anyone an idea how this can be solved or is this not possible.
Or I do the something wrong.
Thanks.
You need to inject the service (spring bean) in the controller instead of creating an instance of it.
package com.test
class DemoController {
def demoService //Autowired, not required to specify in resources.groovy
def index() {
println 'In DemoController.index()'
demoService.serviceMethod()
render 'Hello World'
}
}
Moreover, the aspect can be made annotation based as below:
package com.test.aop.aspect
#Aspect
class LoggerAspect {
//A more generic advice would be as below
//#Before("execution(* com.test.*.*(..))")
#Before("com.test.DemoService.serviceMethod()")
def beforeMethod(){
println '-- Before Method.'
}
//A more generic advice would be as below
//#Around("execution(* com.test.*.*(..))")
#After("com.test.DemoService.serviceMethod()")
def afterMethod(){
println '-- After Method.'
}
}
And resources.groovy could become:
beans = {
loggerAspect(com.test.aop.aspect.LoggerAspect)
xmlns aop:"http://www.springframework.org/schema/aop"
aop{
config("proxy-target-class": true) {
aspect(id: "loggerAspectService", ref: "loggerAspect")
}
}
}

Resources