0
votes

Chargement des propriétés de test application.yml

J'ai un fichier de propriétés de test sous src/test/resources/application.yml . Mais je ne peux pas obtenir les valeurs à charger dans mon test unitaire. J'ai la classe suivante:

Cannot instantiate @InjectMocks field named 'snmpTrapRoute' of type 'class org.meanwhile.in.hell.camel.snmp.receiver.route.SnmpRoute'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : Parameter specified as non-null is null: method org.meanwhile.in.hell.camel.snmp.receiver.route.SnmpTrapRoute.<init>, parameter snmpProperties

qui dans le code de production, charge les valeurs de /src/main/resources/application.yml .

@Configuration
@EnableConfigurationProperties(SnmpProperties::class)
open class TestConfiguration {

    @Bean
    open fun snmpProperties() = SnmpProperties()
}

Classe de test unitaire:

# Test profile
spring:
  profiles: test
snmp:
  port: 1161
  protocol: udp
  host: 0.0.0.0

J'ai essayé d'ajouter un profil de test à chaque fichier application.yml pour voir si l'ajout de @ActiveProfiles("test") fonctionnait, mais ce n'était pas le cas.

src / main / resources / application.yml & src / test / resources / application.yml

@CamelSpringBootTest
@SpringBootApplication
@EnableAutoConfiguration
open class SnmpRouteTest : CamelTestSupport() {

    @Autowired
    lateinit var snmpProperties: SnmpProperties

    @Mock
    lateinit var repository: IPduEventRepository

    @InjectMocks
    lateinit var snmpTrapRoute: SnmpTrapRoute

    @Before
    fun setup() {
        initMocks(this)
    }

J'ai également créé une classe TestConfiguration qui crée le bean SnmpProperties et le transfère automatiquement dans la classe de test en utilisant @EnableConfigurationProperties(TestConfiguration::class) :

snmp:
  port: 1161
  protocol: udp
  host: 0.0.0.0

Encore une fois, non. L'erreur que j'obtiens est:

@ConfigurationProperties("snmp")
open class SnmpProperties {

    var port: Int = 1611
    lateinit var protocol: String
    lateinit var host: String

    override fun toString(): String {
        return "SnmpProperties(port=$port, protocol='$protocol', host='$host')"
    }
}


5 commentaires

vous pouvez surestimer les données que vous souhaitez utiliser dans le profil de test et les mettre dans application-test.yml!


C'est ce que j'ai essayé. J'ai mis à jour ma question pour rendre cela plus clair.


essayez de voir ceci: tuhrig.de/testing-configurationproperties-in-spring-boot ou stackoverflow.com/a/31748450/4373948


Comment avez-vous résolu ce problème?


@DB J'ai ajouté mon test unitaire réécrit comme réponse ci-dessous. Son Camel spécifique. Au lieu de charger les propriétés de test, j'ai remplacé la route "réelle" par une route factice, donc les propriétés de production ont été chargées normalement. Il m'a fallu un certain temps pour le comprendre, mais j'espère que cela aide.


3 Réponses :


0
votes

Assurez-vous de vérifier la structure de votre projet. Le fichier de propriétés doit se trouver sur le chemin de classe pour que Spring Boot le trouve et l'utilise. Par exemple, la structure du projet telle que définie par Maven ici: https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

Dans le cas de Maven, vos fichiers de configuration doivent être placés dans ces répertoires:

src/main/resources/application.yml
src/test/resources/application.yml


1 commentaires

Désolé, j'avais fait une erreur dans ma question concernant le vrai chemin d'accès à mes fichiers YML. J'ai corrigé la mise en page.



0
votes

Il semble que le bean n'est pas créé (d'où l'erreur nulle).

Essayez de:

  • ajoutez @Configuration au-dessus de votre classe de configuration SnmpProperties
  • ajoutez @EnableConfigurationProperties(SnmpProperties.class) en haut de votre classe de test

Source: https://www.baeldung.com/configuration-properties-in-spring-boot


0 commentaires

0
votes
@CamelSpringBootTest
@SpringBootTest(classes = [SnmpTrapReceiverCamelApplication::class])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@DisableJmx(false)
@ExtendWith(MockitoExtension::class)
@EnableAutoConfiguration
class SnmpTrapRouteTest {

    object TestSnmpConstants {
        const val SNMP_REAL_ENDPOINT_ID = "snmp-trap-route"
        const val SNMP_DIRECT_REPLACEMENT_ENDPOINT = "direct:snmp-from"
        const val TRAP_REQUEST_ID = 123456789
        const val TRAP_OID = "1.2.3.4.5"
        const val TRAP_PAYLOAD = "snmp-trap-payload"
    }

    @MockBean
    lateinit var repository: IPduEventRepository

    @Produce
    lateinit var producerTemplate: ProducerTemplate

    @Autowired
    lateinit var camelContext: CamelContext

    @Test
    @Throws(Exception::class)
    fun `Should call save method on the repository when PDU TRAP event supplied`() {

        // Replace our SNMP consumer route with a dummy route than can be called from a producer internally.
        // Since our snmp endpoint is an asynchronous consumer (meaning it only receives data from external events)
        // we need to use the "direct:" component to allow a producer to internally call what is ordinarily an external
        // event-driven endpoint.  Otherwise we will get a Connection Refused error, as we cannot access the external
        // system/socket.
        AdviceWithRouteBuilder.adviceWith(camelContext, TestSnmpConstants.SNMP_REAL_ENDPOINT_ID) { routeBuilder ->
            routeBuilder.replaceFromWith(TestSnmpConstants.SNMP_DIRECT_REPLACEMENT_ENDPOINT)
        }

        // Create the PDU object to send to the SNMP endpoint
        val trap = PDU()
        trap.type = PDU.TRAP
        trap.requestID = Integer32(TestSnmpConstants.TRAP_REQUEST_ID)
        trap.add(VariableBinding(OID(TestSnmpConstants.TRAP_OID), OctetString(TestSnmpConstants.TRAP_PAYLOAD)))

        // "direct:" endpoints only send DefaultMessage objects.  These are not castable to SnmpMessage objects,
        // so need to overwrite the exchange IN message to be an SnmpMessage object
        val exchange = DefaultExchange(camelContext)
        exchange.setIn(SnmpMessage(camelContext, trap))

        // ProducerTemplates need a default endpoint specified.
        // The ProducerTemplate provides us with a producer that can directly deliver messages to consumers defined
        // in the camelContext, using the "direct:" component (see above)
        producerTemplate.setDefaultEndpointUri(TestSnmpConstants.SNMP_DIRECT_REPLACEMENT_ENDPOINT)
        producerTemplate.send(exchange)

        // Verify that the repository.save() was invoked
        verify(repository, atLeast(1)).save(any())
    }
}

0 commentaires