Spring 加载测试应用程序.yml属性
我在Spring 加载测试应用程序.yml属性,spring,spring-boot,unit-testing,kotlin,configurationproperties,Spring,Spring Boot,Unit Testing,Kotlin,Configurationproperties,我在src/test/resources/application.yml下有一个测试属性文件。但是我无法在单元测试中获得要加载的值。我有以下课程: @ConfigurationProperties("snmp") open class SnmpProperties { var port: Int = 1611 lateinit var protocol: String lateinit var host: String override fun toStrin
src/test/resources/application.yml
下有一个测试属性文件。但是我无法在单元测试中获得要加载的值。我有以下课程:
@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')"
}
}
在生产代码中,加载/src/main/resources/application.yml
中的值
snmp:
port: 1161
protocol: udp
host: 0.0.0.0
单元测试类:
@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)
}
我曾尝试向每个应用程序.yml
文件添加测试配置文件,以查看添加@ActiveProfiles(“测试”)
是否有效,但没有效果
src/main/resources/application.yml&
src/test/resources/application.yml
# Test profile
spring:
profiles: test
snmp:
port: 1161
protocol: udp
host: 0.0.0.0
我还创建了一个TestConfiguration类,它创建了SnmpProperties
bean,并使用@EnableConfigurationProperties(TestConfiguration::class)
将其自动连接到测试类中:
再说一遍,不行。我得到的错误是:
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
无法实例化@InjectMocks名为“snmpTrapRoute”的字段,其类型为“class org.syntheld.in.hell.camel.snmp.receiver.route.SnmpRoute”。
您尚未在字段声明中提供实例,因此我尝试构造实例。
但是,构造函数或初始化块引发了异常:指定为非null的参数为null:method org.synthealth.in.hell.camel.snmp.receiver.route.snmptrapproute.,参数snmpProperties
确保检查项目结构。属性文件应该位于类路径上,以便Spring Boot找到并使用它。
例如,Maven在此定义的项目结构:
对于Maven,您的配置文件应放在以下目录中:
src/main/resources/application.yml
src/test/resources/application.yml
看起来没有创建bean(因此出现空错误)
试着:
- 在SnmpProperties配置类的顶部添加
@Configuration
- 在测试类的顶部添加
@EnableConfigurationProperties(SnmpProperties.class)
来源:您可以高估您想要在测试概要文件中使用的数据,并将其放入application-test.yml!这就是我试过的。我已经更新了我的问题以使其更清楚。试着看看这个:或者你是如何解决这个问题的?@D.B我已经在下面添加了我重新编写的单元测试作为答案。它是骆驼特有的。我没有加载测试属性,而是将“真实”路由替换为虚拟路由,因此生产属性按正常方式加载。我花了一段时间才弄明白,但我希望这能有所帮助。对不起,我在我的问题中犯了一个关于我的YML文件的真实路径的错误。我已经修改了布局。
src/main/resources/application.yml
src/test/resources/application.yml
@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())
}
}