当前位置: 首页 > 后端技术 > Java

总结本周遇到的问题_0

时间:2023-04-01 22:29:26 Java

问题一报如下:经过查找,发现此类错误与数据库的字符集有关。当我们存储汉字时,就会出现这样的错误。很显然,我们在建库的时候并没有注意到这些,而且在当前环境下,默认的库是不支持中文的。所以要解决这种错误,只需要修改字符集即可。或者把我们的url改成下面的重建数据库jdbc:mysql://localhost:3310/process-evaluation?useUnicode=true&characterEncoding=utf-8虽然在本地很容易解决,但是如果你只是这样做,在一个remoterobot也会报错,因为在链接的时候仅仅改变url链接并不能直接改变已有数据库的配置。那么我们需要像本地一样重新配置字符集或者重新建立数据库,那么我们需要了解远程机器人的数据库是如何建立的。我们在什么环境下运行流水线,以什么顺序运行,当我们提出PR时,我们要做什么操作?这些配置都与.重复。spring-test:tags:-dockerstage:unit-testimage:maven:3.6-openjdk-8services:-name:mysql:5.7alias:mysqlvariables:MYSQL_ROOT_PASSWORD:rootMYSQL_DATABASE:process-evaluation。..before_script:-cdapiscript:-env-mvn-v-mvnpackagerules:-if:$CI_PIPELINE_SOURCE=='merge_request_event'其中标签定义哪些runner适用于job,我们目前使用的是docker环境,以及里面的image和我们之前配置docker一样遇到的时候遇到的一样,也是指image,所以需要docker环境。这些是它的官方说明——当你配置CI/CD时,你可以在作业运行时使用图像创建容器,但只能有一个图像,如果你需要其他图像,你需要使用服务来指定。一个服务可以创建另一个容器,两个容器可以相互通信。有了这些,我们需要运行后台的环境就只有mysql了,因为需要配置mysql,所以我们使用service来引入。官方也给出了相应的配置方法services:-mysql:latestvariables:#配置mysql环境变量(https://hub.docker.com/_/mysql/)MYSQL_DATABASE:$MYSQL_DATABASEMYSQL_ROOT_PASSWORD:$MYSQL_ROOT_PASSWORD里面的服务项您可以使用来自DockerHub的任何docker镜像,例如,要使用MySQL5.5,请使用mysql:5.5。而imgge可以接受其他环境变量,具体变量与dockerhub中mysql的说明相同。但是以上并不能解决我们遇到的问题——如何更改数据库的字符集?docker环境变量不支持配置字符集,后来发现官方文档也写了如何通过shell运行mysql。但是第一步就出现了问题。当前环境不支持执行aptinstall,不能更改镜像,也不能随意更改通过tags运行的环境。毕竟我们还需要docker环境。所以尝试单独运行一个database-init作业,在上面进行这些操作,但是每个作业都是独立的,也就是说我们在database-init中初始化了数据库,作业结束后,容器就被释放了,后来我们用了一个全新的容器。所以我们只能在服务中进行更改,但是根据官方文档,服务中只能配置环境变量。另外,还有一种方法,自己写一个dockerfile,初始化一个字符集为utf8的docker5.7镜像,通过阿里云构建,最后引入到服务中。这种情况虽然可以解决,但是也会遇到其他的问题,后面我们可以了解到,在服务上做改动可以解决这个问题。这里不再展开。以下是老师给出的解决方案:直接通过命令操作即可。问题虽然解决了,但是新的问题也来了——为什么我找不到这样解决的方法,而且在官方文档中也没有找到这样的操作。后来仔细查看了官方文档,发现确实有对command的解释:acommandorscriptthatshouldbeusedasacontainercommand。它被翻译成在图像名称之后传递给Docker的参数。接下来总是看官方文档,一不留神。这是官方文档的菜单。之前我把所有的注意力都放在了mysql服务上。当看到安装mysql-client可以执行命令时,想当然的认为只有这样才能执行相应的命令。总结:还是要仔细看官方文档,不能自己脑补。可能官方文档的排版与我们平时的阅读习惯不一样,但是遇到问题还是要相信官方文档。问题2:单元测试时出现问题:org.assertj.core.api.Assertions.assertThat(resultUser).isEqualTo(mockResultUser1);首先看看mockResultUser1是怎么从UserService中来的Mockito.any(User.class),Mockito.anyString(),Mockito.anyString());我们将mockResultUser1设置为在调用updateNameAndEmailField时返回。resultUser为null,那我们看看resultUser是从哪里来的。用户user=newUser();用户resultUser=userServiceImplSpy.updateNameAndEmail(id,user);@OverridepublicUserupdateNameAndEmail(Longid,Useruser){UseroldUser=this.userRepository.findById(id).get();返回this.updateNameAndEmailField(oldUser,user.getName(),user.getEmail());}publicUserupdateNameAndEmailField(UseroldUser,Stringname,Stringemail){oldUser.setName(name);oldUser.setEmail(email);返回这个.userRepository.save(oldUser);}了解了大概的流程之后,接下来就是管理了,观察为什么断言不成立,哪一部分和我们的预期不一样。我们可以看到在最外层传参是没有问题的,resultUser确实为null。那么就需要在服务层进一步管理。updateNameAndEmaile也没有问题。这里可以发现问题,email为null,说明我们没有给email设置初始值,但是执行过程中没有报错,说明这个也是可以的,比如我们也可以在当前情况为空,因为我们的错误只是由于不正确的断言。那么为什么会返回null,主要是因为:Mockito.doReturn(mockResultUser1).when(userServiceImplSpy).updateNameAndEmailField(Mockito.any(User.class),Mockito.anyString(),Mockito.anyString());我们设置传递给updateNameAndEmailField(user,String,String)时,会返回mockResultUser1,但是null不在Mockito.anyString()的范围内,所以会返回null。如果我们改成Mockito.any(),就不会出现上面的断言错误了。当然,我们还是应该按照原来的思路给email设置初始值,最好在updateNameAndEmailField中加一个断言。,Assert.notNull(email,"emailcannotbenull");这样我们在执行单元测试的时候就可以清楚的知道问题出在哪里了。