Spring引导和Spring数据休息集成测试无法持久数据(Spring boot & Spring data rest integration test fails to persist data)
我正在使用Spring Boot和Spring Data Rest来公开我的数据存储库。
我编写的集成测试将用户添加到数据库,然后调用其余方法列出用户。 但添加的用户不在列表中。
一个ApplicationRunner被用来填充数据库和我使用Spring配置文件不同的数据库。
例如,对于我的测试:
spring: profiles: unittest datasource: url: 'jdbc:h2:mem:MYDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' driver-class-name: org.h2.Driver username: myname password: mypassword jpa: show-sql: true hibernate: ddl-auto: create-drop jpa: hibernate: dialect: org.hibernate.dialect.H2Dialect
单元测试:
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("unittest") @AutoConfigureTestEntityManager @Transactional public class MyUserRepoIntegrationTest { private static Logger log = Logger.getLogger(MyUserRepoIntegrationTest.class); // 3 default users + "test" private static final int NUM_USERS = 4; @Autowired private TestRestTemplate restTemplate; @Autowired private TestEntityManager entityManager; @Before public void setupTests() { entityManager.persistAndFlush(new MyUser("test", "test")); } @Test public void listUsers() { ResponseEntity<String> response = restTemplate.withBasicAuth("user", "user").getForEntity("/apiv1/data/users", String.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getBody()).contains("\"totalElements\" : "+NUM_USERS); } }
最后的断言总是失败。 数据库中只有3个用户,由ApplicationRunner添加(通过userRepository)。 我已经尝试使用userRepository而不是TestEntityManager,并在测试方法本身内添加用户,但没有任何更改。
我已经验证过,它使用H2而不是我的生产数据库。
编辑:
经过仔细检查,数据实际上到达数据库。 当我注入UserRepository并调用.count()时,它给了我NUM_USERS(4)。
问题可能在于Spring Data REST,因为REST响应不包括新用户。 我也尝试修改一个现有的用户并显式调用flush(),但响应仍然是一样的。 我已经从我的POM中删除了'spring-boot-starter-cache',并在'unittest'配置文件中为我的application.yml添加了spring.cache.type = none,但没有运气。
I'm using Spring Boot and Spring Data Rest to expose my Data repository.
The integration test I wrote, adds a user to the database and then calls the rest method to lists users. But the added user is NOT being listed.
An ApplicationRunner is used to populate the DB with data and I'm using Spring profiles for differnt databases.
For example, for my tests:
spring: profiles: unittest datasource: url: 'jdbc:h2:mem:MYDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' driver-class-name: org.h2.Driver username: myname password: mypassword jpa: show-sql: true hibernate: ddl-auto: create-drop jpa: hibernate: dialect: org.hibernate.dialect.H2Dialect
The unit test:
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("unittest") @AutoConfigureTestEntityManager @Transactional public class MyUserRepoIntegrationTest { private static Logger log = Logger.getLogger(MyUserRepoIntegrationTest.class); // 3 default users + "test" private static final int NUM_USERS = 4; @Autowired private TestRestTemplate restTemplate; @Autowired private TestEntityManager entityManager; @Before public void setupTests() { entityManager.persistAndFlush(new MyUser("test", "test")); } @Test public void listUsers() { ResponseEntity<String> response = restTemplate.withBasicAuth("user", "user").getForEntity("/apiv1/data/users", String.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getBody()).contains("\"totalElements\" : "+NUM_USERS); } }
The last assertion always fails. There are only 3 users in the DB, the ones added by the ApplicationRunner (via the userRepository). I've tried using the userRepository instead of the TestEntityManager and adding the user inside the test method itself, but nothing changes.
I've verified, that it's using H2 and not my production DB.
EDIT:
Upon closer inspection, the Data actually gets to the Database. When I inject my UserRepository and call .count(), it gives me NUM_USERS (4).
The Problem probably lies with Spring Data REST, since the REST response doesn't include the new user. I've also tried modifying an existing user and explicitly calling flush(), yet the response is still the same. I've removed 'spring-boot-starter-cache' from my POM and added spring.cache.type=none to my application.yml for the 'unittest' profile, but no luck.
原文:https://stackoverflow.com/questions/41099879
最满意答案
回答我自己的问题(对其他人)。
解决方案是将每个样本(当16位PCM为2个字节时)乘以常数值。
避免溢出\大大增加你可以通过寻找最高样本值来计算你可以使用的最高常数值,并计算乘法因子以使其达到最高样本值,在16位PCM情况下,即32676或其他东西。
这是一个小例子:
public byte[] IncreaseDecibel(byte[] audioBuffer, float multiplier) { // Max range -32768 and 32767 var highestValue = GetHighestAbsoluteSample(audioBuffer); var highestPosibleMultiplier = (float)Int16.MaxValue/highestValue; // Int16.MaxValue = 32767 if (multiplier > highestPosibleMultiplier) { multiplier = highestPosibleMultiplier; } for (var i = 0; i < audioBuffer.Length; i = i + 2) { Int16 sample = BitConverter.ToInt16(audioBuffer, i); sample *= (Int16)(sample * multiplier); byte[] sampleBytes = GetLittleEndianBytesFromShort(sample); audioBuffer[i] = sampleBytes[sampleBytes.Length-2]; audioBuffer[i+1] = sampleBytes[sampleBytes.Length-1]; } return audioBuffer; }
To answer my own question (for others).
The solution is to multiply every sample (when 16bit PCM that are 2 bytes) with a constant value.
Do avoid overflow\to much increase you can calculate the highest constant value you can use by looking for the highest sample value and calculate the multiply factor to get it to highest sample value possible, in 16bit PCM case thats 32676 or something.
Here is litle example:
public byte[] IncreaseDecibel(byte[] audioBuffer, float multiplier) { // Max range -32768 and 32767 var highestValue = GetHighestAbsoluteSample(audioBuffer); var highestPosibleMultiplier = (float)Int16.MaxValue/highestValue; // Int16.MaxValue = 32767 if (multiplier > highestPosibleMultiplier) { multiplier = highestPosibleMultiplier; } for (var i = 0; i < audioBuffer.Length; i = i + 2) { Int16 sample = BitConverter.ToInt16(audioBuffer, i); sample *= (Int16)(sample * multiplier); byte[] sampleBytes = GetLittleEndianBytesFromShort(sample); audioBuffer[i] = sampleBytes[sampleBytes.Length-2]; audioBuffer[i+1] = sampleBytes[sampleBytes.Length-1]; } return audioBuffer; }
相关问答
更多-
音频和振幅(Audio frequency and amplitude)[2022-07-26]
Apple的aurioTouch示例应用程序似乎是使用某些C ++编写的,绝对没有理由。 将代码转换为plain C,也许你会更好地理解它。 近乎实时的DSP音频分析并没有那么容易,所以请阅读该主题。 Apple's aurioTouch sample app appears to be written using some C++ for absolutely no reason. Convert the code to plain C, and maybe you'll understand it be ... -
你在这里做的是对时变模拟信号进行采样。 所以是的,你获得的价值是PCM - 但有一个巨大的警告(见下文)。 如果你把它们写成WAV文件(可能用这个来帮你),你可以在Audacity中打开它们。 您可以将值转换为无符号的8位(通过截断和),或者将16位带符号的移位和减法转换。 需要注意的是PCM是带有信号的采样时钟的调制。 在你的情况下,时钟信号是你对ADC进行位反转的频率。 实际上,要在软件中规定这是非常困难的 - 特别是在使用诸如Python等高级语言对设备进行位撞时。 你需要以信号带宽的两倍进行采样(奈 ...
-
回答我自己的问题(对其他人)。 解决方案是将每个样本(当16位PCM为2个字节时)乘以常数值。 避免溢出\大大增加你可以通过寻找最高样本值来计算你可以使用的最高常数值,并计算乘法因子以使其达到最高样本值,在16位PCM情况下,即32676或其他东西。 这是一个小例子: public byte[] IncreaseDecibel(byte[] audioBuffer, float multiplier) { // Max range -32768 and 32767 ...
-
您可以使用Accelerate.framework快速轻松地完成此操作。 既然你使用AudioUnits我假设你已经去交错浮动缓冲区,所以这样的事情应该工作: float desiredGain = 1.06f; // or whatever linear gain you'd like AudioBufferList *ioData; // audio from somewhere for(UInt32 bufferIndex = 0; bufferIndex < ioData->mNumberBuffe ...
-
没有这样的选择,可能期望在接收方控制这一点。 您可以尝试“声音”属性(男人,女人,爱丽丝)的价值,并看到(听到)哪一个听起来更适合您的情况。 通常,更清晰的声音会弥补响度。 https://www.twilio.com/docs/api/twiml/say There is no such option, is probably expected for this to be controlled on the receiving side. You can experiment with the valu ...
-
你需要做的是建立一个过滤器图并通过该图处理音频流。 在你的情况下,图形只是INPUT(“abuffer”) - > VOLUME - > OUTPUT(“abuffersink”)。 这是一个示例控制台应用程序,演示。 它松散地基于ffmpeg样本filtering_audio , filter_audio和remuxing 。 你可以像这样使用它: ChangeVolume.exe http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4 bunn ...
-
只需将MAXVOL增加到100000(原始值的150%,65537)即可。 I managed to change it by adding an new variable and to some math. The OVERMAX value (adjust to desired max percentage) is used to set a new percentage value. So 130% becomes 100%. #!/bin/sh # pulsevol.sh # PulseAu ...
-
cpp原始音频到模拟值(cpp raw audio to analog values)[2023-09-30]
你的类型到处都是。 模拟读取被声明为返回uint8_t,但它在实际实现中返回一个double。您似乎误解了read()函数或sizeof运算符。 第一个参数是正确的,它是文件descritpor。 第二个参数是缓冲区,它也是正确的。 第三个参数是缓冲区的大小。 这不是由sizeof运算符获得的,而是使用BUFFER_SIZE*sizeof(uint8_t) 。 此外,你是命令行争论说以cd格式输出音频。 CD格式使用两个轨道来创建立体声效果,我们只对uspeech感兴趣。 如果查看arecord的手册页,它 ... -
将音频双精度转换为字节(Convert audio doubles to bytes)[2024-01-09]
由于另一个函数所需的格式是16位,48 kHz,这与源数据相同,因此将源转换为Short数组的简单情况,然后将其序列化为Byte数组。 您建议的代码问题是错过了第一步,因此它基本上序列化了Double数组。 但是,您可以在第二步重复使用它。 所以,你可以这样做: Dim nShorts() As Short = New Short(nDoubles.Length - 1) {} For i = 0 To nDoubles.Length - 1 nShorts(i) = Co ... -
Web Audio API为此提供了库函数 。 AudioParam.linearRampToValueAtTime(value, endTime) 值 一个浮点数,表示AudioParam在给定时间内将进入的值。 时间结束 一个双精度表示斜坡开始后的确切时间(以秒为单位),将停止更改值。 所以在你的情况下使用 gainNode.gain.linearRampToValueAtTime(0, 0) gainNode.gain.linearRampToValueAtTime(1, 2) The Web A ...