Git Product home page Git Product logo

Comments (10)

urmichm avatar urmichm commented on June 11, 2024

Similar issue is about DataSource.

NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate.

Data source is a nested bean far down the hierarchy of beans. Running a Unit Test, i am just expecting a UNIT peace of code to be tested. No need for data source or loading all the beans of the application.

from grails-core.

osscontributor avatar osscontributor commented on June 11, 2024

@urmichm Does the test at https://github.com/osscontributor/issue13506/blob/25d620dd85b666ba5c0a3b9ad194dcabc739ac63/src/test/groovy/issue13506/MyControllerSpec.groovy pass for you?

from grails-core.

urmichm avatar urmichm commented on June 11, 2024

Hello, unfortunately no.
I am getting an exceptions during the initializationError that some other Beans are not created.
example: NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate.
The DataSource is required in an unrelated Service which is in some other unrelated Controller.

from grails-core.

osscontributor avatar osscontributor commented on June 11, 2024

Hello, unfortunately no.

That is interesting.

Are you using Gradle to run the test?

This is what I am seeing: https://gist.github.com/osscontributor/1786f4cce7e73aa943f3f6fc479fc4b4

from grails-core.

osscontributor avatar osscontributor commented on June 11, 2024

The DataSource is required in an unrelated Service which is in some other unrelated Controller.

I have tried a few combinations of class dependencies and I haven't yet been able to reproduce the problem. If you could send a PR to the repo I linked above with a combination of things that recreates the problem, that would prove helpful in troubleshooting.

from grails-core.

urmichm avatar urmichm commented on June 11, 2024

Maybe let me paraphrase the question. @osscontributor how do you mock or configure DataSource for unit tests?

from grails-core.

osscontributor avatar osscontributor commented on June 11, 2024

how do you mock or configure DataSource for unit tests?

If you are using GORM, you generally wouldn't. The more common thing is to kind of mock GORM using the default implementation that is configured in unit tests which uses a Map backed store. It is unusual for a controller to interact directly with a DataSource.

If you can provide a sample app which demonstrates what you are trying to test I would be happy to send you a PR or identify if there is relevant bug in the framework.

Thank you for the feedback.

from grails-core.

urmichm avatar urmichm commented on June 11, 2024

Hello @osscontributor
The controller does not interact with a DataSource. The other controller has a service which has a bean which has a DataSource bean. I do not understand why the other controller and all its hierarchy of the beans is created. I do not need it. I just need a unit test for MyController. My question is about mocking the beans i do not need. Especially mocking a DataSource bean from a random Bean of a random Service from an unrelated Controller.
I the unit tests I want to make the DataSource is not required at all, since as you mentioned DataSource is not there (at least directly)

from grails-core.

osscontributor avatar osscontributor commented on June 11, 2024

@urmichm Can you share a link to a sample project which demonstrates the problem?

from grails-core.

puneetbehl avatar puneetbehl commented on June 11, 2024

I assume that it might be that you are calling another controller from the one under unit test. But, if could share the code which is unit tested here or better a sample application that'd be helpful to debug the issue.

Generally, you would mock any service which is being called from the controller. Let's walk through an example:

  1. Suppose you have a BookController.groovy which inject a service named BookService as:

    grails-app/controllers/com/example/BookController.groovy

    package com.example
    
    import grails.rest.RestfulController
    
    class BookController extends RestfulController<Book> {
    
        BookService bookService
    
        BookController() {
            super(Book)
        }
    
        def show(Long id) {
            def book = bookService.getBookById(id)
            if (book) {
                respond book
            } else {
                render status: 404
            }
        }
    }
  2. Here is the code from BookService:

    grails-app/services/com/example/BookService.groovy

    package com.example
    
    import groovy.sql.Sql
    import javax.sql.DataSource
    
    class BookService {
    
        DataSource dataSource
    
        Book getBookById(Long id) {
            Sql sql = new Sql(dataSource)
            def row = sql.firstRow('SELECT * FROM book WHERE id = ?', [id])
            if (row) {
                new Book(row)
            } else {
                null
            }
        }
    }
  3. Ensure that the DataSource is properly configured in application.yml or application.groovy. Grails typically auto-configures the DataSource based on the environment.

    grails-app/config/application.yml

    dataSource:
        pooled: true
        driverClassName: org.h2.Driver
        username: sa
        password: ''
        dbCreate: update
        url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    
    environments:
        development:
            dataSource:
                dbCreate: update
                url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        test:
            dataSource:
                dbCreate: update
                url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        production:
            dataSource:
                dbCreate: update
                url: jdbc:h2:file:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
  4. When you write the unit tests for BookController.groovy then you might mock the BookService and test controller as:

    package com.example
    
    import grails.testing.web.controllers.ControllerUnitTest
    import spock.lang.Specification
    
    class BookControllerSpec extends Specification implements ControllerUnitTest<BookController> {
    
        def bookService = Mock(BookService)
    
        void setup() {
            controller.bookService = bookService
        }
    
        void "test show action with existing book"() {
            given:
            def book = new Book(title: "Grails in Action")
            bookService.getBookById(1L) >> book
    
            when:
            controller.show(1L)
    
            then:
            response.status == 200
            response.json.title == "Grails in Action"
        }
    
        void "test show action with non-existing book"() {
            given:
            bookService.getBookById(1L) >> null
    
            when:
            controller.show(1L)
    
            then:
            response.status == 404
        }
    }
  5. When writing a unit test for BookService, you might mock the DataSource and test the service logic.

    package com.example
    
    import grails.testing.services.ServiceUnitTest
    import spock.lang.Specification
    import groovy.sql.Sql
    import javax.sql.DataSource
    
    class BookServiceSpec extends Specification implements ServiceUnitTest<BookService> {
    
        def dataSource = Mock(DataSource)
        def sql = Mock(Sql)
    
        void setup() {
            service.dataSource = dataSource
        }
    
        void "test getBookById with existing book"() {
            given:
            def mockRow = [id: 1L, title: 'Grails in Action']
            sql.firstRow('SELECT * FROM book WHERE id = ?', [1L]) >> mockRow
    
            when:
            def book = service.getBookById(1L)
    
            then:
            1 * dataSource.connection >> Mock(Connection)
            1 * new Sql(connection) >> sql
            1 * sql.firstRow('SELECT * FROM book WHERE id = ?', [1L]) >> mockRow
            book.title == 'Grails in Action'
        }
    
        void "test getBookById with non-existing book"() {
            given:
            sql.firstRow('SELECT * FROM book WHERE id = ?', [1L]) >> null
    
            when:
            def book = service.getBookById(1L)
    
            then:
            1 * dataSource.connection >> Mock(Connection)
            1 * new Sql(connection) >> sql
            1 * sql.firstRow('SELECT * FROM book WHERE id = ?', [1L]) >> null
            book == null
        }
    }

Please note that above examples are only for reference. I didn't get the chance to verify this manually but would need to mock things as per the application and the specific services, methods, or contructors.

from grails-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.