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')" } }
3 Réponses :
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
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.
Il semble que le bean n'est pas créé (d'où l'erreur nulle).
Essayez de:
@Configuration
au-dessus de votre classe de configuration SnmpProperties@EnableConfigurationProperties(SnmpProperties.class)
en haut de votre classe de testSource: https://www.baeldung.com/configuration-properties-in-spring-boot
@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()) } }
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.