专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

Java单元测试浅析(JUnitMockito)

  作者:京东物流秦彪1。什么是单元测试
  (1)单元测试环节:
  测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:
  1)单元测试:针对计算机程序模块进行输出正确性检验工作。
  2)集成测试:在单元测试基础上,整合各个模块组成子系统,进行集成测试。
  3)系统测试:将整个交付所涉及的协作内容都纳入其中考虑,包含计算机硬件、软件、接口、操作等等一系列作为一个整体,检验是否满足软件或需求说明。
  4)验收测试:在交付或者发布之前对所做的工作进行测试检验。
  单元测试是阶段性测试的首要环节,也是白盒测试的一种,该内容的编写与实践可以前置在研发完成,研发在编写业务代码的时候就需要生成对应代码的单元测试。单元测试的发起人是程序设计者,受益人也是编写程序的人,所以对于程序员,非常有必要形成自我约束力,完成基本的单元测试用例编写。
  (2)单元测试特征:
  由上可知,单元测试其实是针对软件中最小的测试单元来进行验证的。这里的单元就是指相关的功能子集,比如一个方法、一个类等。值得注意的是作为最低级别的测试活动,单元测试验证的对象仅限于当前测试内容,与程序其它部分内容相隔离,总结起来单元测试有以下特征:
  1)主要功能是证明编写的代码内容与期望输出一致。
  2)最小最低级的测试内容,由程序员自身发起,保证程序基本组件正常。
  3)单元测试尽量不要区分类与方法,主张以过程性的方法为测试单位,简单实用高效为目标。
  4)不要偏离主题,专注于测试一小块的代码,保证基础功能。
  5)剥离与外部接口、存储之间的依赖,使单元测试可控。
  6)任何时间任何顺序执行单元测试都需要是成功的。2。为什么要单元测试
  (1)单元测试意义:
  程序代码都是由基本单元不断组合成复杂的系统,底层基本单元都无法保证输入输出正确性,层级递增时,问题就会不断放大,直到整个系统崩溃无法使用。所以单元测试的意义就在于保证基本功能是正常可用且稳定的。而对于接口、数据源等原因造成的不稳定因素,是外在原因,不在单元测试考虑范围之内。
  (2)使用main方法进行测试:PostMapping(valuesave)publicMapString,Objectsave(RequestBodyStudentstu){studentService。save(stu);MapString,ObjectparamsnewHashMap();params。put(code,200);params。put(message,保存成功);returnparams;}
  假如要对上面的Controller进行测试,可以编写如下的代码示例,使用main方法进行测试的时候,先启动整个工程应用,然后编写main方法如下进行访问,在单步调试代码。publicstaticvoidmain(String〔〕args){HttpHeadersheadersnewHttpHeaders();headers。setContentType(MediaType。APPLICATIONJSON);Stringjson{name:张三,className:三年级一班,age:20,sex:男};HttpEntityStringhttpEntitynewHttpEntity(json,headers);Stringurlhttp:localhost:9092studentsave;MainMethodTesttestnewMainMethodTest();ResponseEntityMapresponseEntitytest。getRestTemplate()。postForEntity(url,httpEntity,Map。class);System。out。println(responseEntity。getBody());}
  (3)使用main方法进行测试的缺点:
  1)通过编写大量的main方法针对每个内容做打印输出到控制台枯燥繁琐,不具备优雅性。
  2)测试方法不能一起运行,结果需要程序员自己判断正确性。
  3)统一且重复性工作应该交给工具去完成。3。单元测试框架JUnit3。1JUnit简介
  JUnit官网:https:junit。org。JUnit是一个用于编写可重复测试的简单框架。它是用于单元测试框架的xUnit体系结构的一个实例。
  JUnit的特点:
  (1)针对于Java语言特定设计的单元测试框架,使用非常广泛。
  (2)特定领域的标准测试框架。
  (3)能够在多种IDE开发平台使用,包含Idea、Eclipse中进行集成。
  (4)能够方便由Maven引入使用。
  (5)可以方便的编写单元测试代码,查看测试结果等。
  JUnit的重要概念:
  名称
  功能作用
  Assert
  断言方法集合
  TestCase
  表示一个测试案例
  TestSuite
  包含一组TestCase,构成一组测试
  TestResult
  收集测试结果
  JUnit的一些注意事项及规范:
  (1)测试方法必须使用Test修饰
  (2)测试方法必须使用publicvoid进行修饰,不能带参数
  (3)测试代码的包应该和被测试代码包结构保持一致
  (4)测试单元中的每个方法必须可以独立测试,方法间不能有任何依赖
  (5)测试类一般使用Test作为类名的后缀
  (6)测试方法使一般用test作为方法名的前缀
  JUnit失败结果说明:
  (1)Failure:测试结果和预期结果不一致导致,表示测试不通过
  (2)error:由异常代码引起,它可以产生于测试代码本身的错误,也可以是被测代码的Bug3。2JUnit内容
  (1)断言的API
  断言方法
  断言描述
  assertNull(Stringmessage,Objectobject)
  检查对象是否为空,不为空报错
  assertNotNull(Stringmessage,Objectobject)
  检查对象是否不为空,为空报错
  assertEquals(Stringmessage,Objectexpected,Objectactual)
  检查对象值是否相等,不相等报错
  assertTrue(Stringmessage,booleancondition)
  检查条件是否为真,不为真报错
  assertFalse(Stringmessage,booleancondition)
  检查条件是否为假,为真报错
  assertSame(Stringmessage,Objectexpected,Objectactual)
  检查对象引用是否相等,不相等报错
  assertNotSame(Stringmessage,Objectunexpected,Objectactual)
  检查对象引用是否不等,相等报错
  assertArrayEquals(Stringmessage,Object〔〕expecteds,Object〔〕actuals)
  检查数组值是否相等,遍历比较,不相等报错
  assertArrayEquals(Stringmessage,Object〔〕expecteds,Object〔〕actuals)
  检查数组值是否相等,遍历比较,不相等报错
  assertThat(Stringreason,Tactual,Matcherlt;?superTmatcher)
  检查对象是否满足给定规则,不满足报错
  (2)JUnit常用注解:
  1)Test:定义一个测试方法Test(exceptedxx。class):xx。class表示异常类,表示测试的方法抛出此异常时,认为是正常的测试通过的Test(timeout毫秒数):测试方法执行时间是否符合预期。
  2)BeforeClass:在所有的方法执行前被执行,static方法全局只会执行一次,而且第一个运行。
  3)AfterClass:在所有的方法执行之后进行执行,static方法全局只会执行一次,最后一个运行。
  4)Before:在每一个测试方法被运行前执行一次。
  5)After:在每一个测试方法运行后被执行一次。
  6)Ignore:所修饰的测试方法会被测试运行器忽略。
  7)RunWith:可以更改测试执行器使用junit测试执行器。3。3JUnit使用3。3。1Controller层单元测试
  (1)Springboot中使用maven引入Junit非常简单,使用如下依赖即可引入:dependencygroupIdorg。springframework。bootgroupIdspringbootstartertestartifactIdscopetestscopedependency
  (2)上面使用main方法案例可以使用如下的Junit代码完成:RunWith(SpringRunner。class)SpringBootTest(classesMainApplication。class)publicclassStudentControllerTest{注入Spring容器AutowiredprivateWebApplicationContextapplicationContext;模拟Http请求privateMockMvcmockMvc;BeforepublicvoidsetupMockMvc(){初始化MockMvc对象mockMvcMockMvcBuilders。webAppContextSetup(applicationContext)。build();}新增学生测试用例throwsExceptionTestpublicvoidaddStudent()throwsException{Stringjson{name:张三,className:三年级一班,age:20,sex:男};mockMvc。perform(MockMvcRequestBuilders。post(studentsave)构造一个post请求发送端和接收端数据格式。contentType(MediaType。APPLICATIONJSONUTF8)。accept(MediaType。APPLICATIONJSONUTF8)。content(json。getBytes()))断言校验返回的code编码。andExpect(MockMvcResultMatchers。status()。isOk())添加处理器打印返回结果。andDo(MockMvcResultHandlers。print());}}
  只需要在类或者指定方法上右键执行即可,可以直接充当postman工作访问指定url,且不需要写请求代码,这些都由工具自动完成。
  (3)案例中相关组件介绍
  本案例中构造mockMVC对象时,也可以使用如下方式:AutowiredprivateStudentControllerstudentController;BeforepublicvoidsetupMockMvc(){初始化MockMvc对象mockMvcMockMvcBuilders。standaloneSetup(studentController)。build();}
  其中MockMVC是Spring测试框架提供的用于REST请求的工具,是对Http请求的模拟,无需启动整个模块就可以对Controller层进行调用,速度快且不依赖网络环境。
  使用MockMVC的基本步骤如下:
  1)mockMvc。perform执行请求
  2)MockMvcRequestBuilders。post或get构造请求
  3)MockHttpServletRequestBuilder。param或content添加请求参数
  4)MockMvcRequestBuilders。contentType添加请求类型
  5)MockMvcRequestBuilders。accept添加响应类型
  6)ResultActions。andExpect添加结果断言
  7)ResultActions。andDo添加返回结果后置处理
  8)ResultActions。andReturn执行完成后返回相应结果3。3。2Service层单元测试
  可以编写如下代码对Service层查询方法进行单测:RunWith(SpringRunner。class)SpringBootTestpublicclassStudentServiceTest{AutowiredprivateStudentServicestudentService;TestpublicvoidgetOne()throwsException{StudentstustudentService。selectByKey(5);Assert。assertThat(stu。getName(),CoreMatchers。is(张三));}}
  执行结果:
  3。3。3Dao层单元测试
  可以编写如下代码对Dao层保存方法进行单测:RunWith(SpringRunner。class)SpringBootTestpublicclassStudentDaoTest{AutowiredprivateStudentMapperstudentMapper;TestRollback(valuetrue)TransactionalpublicvoidinsertOne()throwsException{StudentstudentnewStudent();student。setName(李四);student。setMajor(计算机学院);student。setAge(25);student。setSex(男);intcountstudentMapper。insert(student);Assert。assertEquals(1,count);}}
  其中Rollback(valuetrue)可以执行单元测试之后回滚所新增的数据,保持数据库不产生脏数据。3。3。4异常测试
  (1)在service层定义一个异常情况:publicvoidcomputeScore(){inta10,b0;}
  (2)在service的测试类中定义单元测试方法:Test(expectedArithmeticException。class)publicvoidcomputeScoreTest(){studentService。computeScore();}
  (3)执行单元测试也会通过,原因是Test注解中的定义了异常
  3。3。5测试套件测多个类
  (1)新建一个空的单元测试类
  (2)利用注解RunWith(Suite。class)和SuiteClasses标明要一起单元测试的类RunWith(Suite。class)Suite。SuiteClasses({StudentServiceTest。class,StudentDaoTest。class})publicclassAllTest{}
  运行结果:
  3。3。6idea中查看单元测试覆盖率
  (1)单测覆盖率
  测试覆盖率是衡量测试过程工作本身的有效性,提升测试效率和减少程序bug,提升产品可靠性与稳定性的指标。
  统计单元测试覆盖率的意义:
  1)可以洞察整个代码中的基础组件功能的所有盲点,发现相关问题。
  2)提高代码质量,通常覆盖率低表示代码质量也不会太高,因为单测不通过本来就映射出考虑到各种情况不够充分。
  3)从覆盖率的达标上可以提高代码的设计能力。
  (2)在idea中查看单元测试覆盖率很简单,只需按照图中示例的图标运行,或者在单元测试方法或类上右键RunxxxwithCoverage即可。执行结果是一个表格,列出了类、方法、行数、分支覆盖情况。
  (3)在代码中会标识出覆盖情况,绿色的是已覆盖的,红色的是未覆盖的。
  (4)如果想要导出单元测试的覆盖率结果,可以使用如下图所示的方式,勾选OpengeneratedHTMLinbrowser
  导出结果:
  3。3。7JUnit插件自动生成单测代码
  (1)安装插件,重启idea生效
  (2)配置插件
  (3)使用插件
  在需要生成单测代码的类上右键generate。。。,如下图所示。
  生成结果:
  4。单元测试工具Mockito4。1Mockito简介
  在单元测试过程中主张不要依赖特定的接口与数据来源,此时就涉及到对相关数据的模拟,比如Http和JDBC的返回结果等,可以使用虚拟对象即Mock对象进行模拟,使得单元测试不在耦合。
  Mock过程的使用前提:
  (1)实际对象时很难被构造出来的
  (2)实际对象的特定行为很难被触发
  (3)实际对象可能当前还不存在,比如依赖的接口还没有开发完成等等。
  Mockito官网:https:site。mockito。org。Mockito和JUnit一样是专门针对Java语言的mock数据框架,它与同类的EasyMock和jMock功能非常相似,但是该工具更加简单易用。
  Mockito的特点:
  (1)可以模拟类不仅仅是接口
  (2)通过注解方式简单易懂
  (3)支持顺序验证
  (4)具备参数匹配器4。2Mockito使用
  maven引入springbootstartertest会自动将mockito引入到工程中。4。2。1使用案例
  (1)在之前的代码中在定义一个BookService接口,含义是借书接口,暂且不做实现publicinterfaceBookService{BookorderBook(Stringname);}
  (2)在之前的StudentService类中新增一个orderBook方法,含义是学生预定书籍方法,其中实现内容调用上述的BookService的orderBook方法。publicBookorderBook(Stringname){returnbookService。orderBook(name);}
  (3)编写单元测试方法,测试StudentService的orderBook方法TestpublicvoidorderBookTest(){BookexpectBooknewBook(1L,钢铁是怎样炼成的,书架A01);Mockito。when(bookService。orderBook(any(String。class)))。thenReturn(expectBook);BookbookstudentService。orderBook();System。out。println(book);Assert。assertTrue(预定书籍不符,expectBook。equals(book));}
  (4)执行结果:
  (5)结果解析
  上述内容并没有实现BookService接口的orderBook(Stringname)方法。但是使用mockito进行模拟数据之后,却通过了单元测试,原因就在于Mockito替换了本来要在StudentService的orderBook方法中获取的对象,此处就模拟了该对象很难获取或当前无法获取到,用模拟数据进行替代。
  4。2。2相关语法
  常用API:
  上述案例中用到了mockito的when、any、theWhen等语法。接下来介绍下都有哪些常用的API:
  1)mock:模拟一个需要的对象
  2)when:一般配合thenXXX一起使用,表示当执行什么操作之后怎样。
  3)any:返回一个特定对象的缺省值,上例中标识可以填写任何String类型的数据。
  4)theReturn:在执行特定操作后返回指定结果。
  5)spy:创造一个监控对象。
  6)verify:验证特定的行为。
  7)doReturn:返回结果。
  8)doThrow:抛出特定异常。
  9)doAnswer:做一个自定义响应。
  10)times:操作执行次数。
  11)atLeastOnce:操作至少要执行一次。
  12)atLeast:操作至少执行指定的次数。
  13)atMost:操作至多执行指定的次数。
  14)atMostOnce:操作至多执行一次。
  15)doNothing:不做任何的处理。
  16)doReturn:返回一个结果。
  17)doThrow:抛出一个指定异常。
  18)doAnswer:指定一个特定操作。
  19)doCallRealMethod:用于监控对象返回一个真实结果。4。2。3使用要点
  (1)打桩
  Mockito中有Stub,所谓存根或者叫打桩的概念,上面案例中的Mockito。when(bookService。orderBook(any(String。class)))。thenReturn(expectBook);就是打桩的含义,先定义好如果按照既定的方式调用了什么,结果就输出什么。然后在使用BookbookstudentService。orderBook();即按照指定存根输出指定结果。TestpublicvoidverifyTest(){ListmockedListmock(List。class);mockedList。add(one);verify(mockedList)。add(one);验证通过,因为前面定义了这个桩verify(mockedList)。add(two);验证失败,因为前面没有定义了这个桩}
  (2)参数匹配
  上例StudentService的orderBook方法中的any(String。class)即为参数匹配器,可以匹配任何此处定义的String类型的数据。
  (3)次数验证TestpublicvoidtimesTest(){ListmockedListmock(List。class);when(mockedList。get(anyInt()))。thenReturn(1000);System。out。println(mockedList。get(1));System。out。println(mockedList。get(1));System。out。println(mockedList。get(1));System。out。println(mockedList。get(2));验证通过:get(1)被调用3次verify(mockedList,times(3))。get(1);验证通过:get(1)至少被调用1次verify(mockedList,atLeastOnce())。get(1);验证通过:get(1)至少被调用3次verify(mockedList,atLeast(3))。get(1);}
  (4)顺序验证TestpublicvoidorderBookTest1(){Stringjson{id:12,location:书架A12,name:三国演义};Stringjson1{id:21,location:书架A21,name:水浒传};Stringjson2{id:22,location:书架A22,name:红楼梦};Stringjson3{id:23,location:书架A23,name:西游记};when(bookService。orderBook())。thenReturn(JSON。parseObject(json,Book。class));BookbookbookService。orderBook();Assert。assertTrue(预定书籍有误,三国演义。equals(book。getName()));when(bookService。orderBook())。thenReturn(JSON。parseObject(json1,Book。class))。thenReturn(JSON。parseObject(json2,Book。class))。thenReturn(JSON。parseObject(json3,Book。class));Bookbook1bookService。orderBook();Bookbook2bookService。orderBook();Bookbook3bookService。orderBook();Bookbook4bookService。orderBook();Bookbook5bookService。orderBook();全部验证通过,按顺序最后打桩打了3次,大于3次按照最后对象输出Assert。assertTrue(预定书籍有误,水浒传。equals(book1。getName()));Assert。assertTrue(预定书籍有误,红楼梦。equals(book2。getName()));Assert。assertTrue(预定书籍有误,西游记。equals(book3。getName()));Assert。assertTrue(预定书籍有误,西游记。equals(book4。getName()));Assert。assertTrue(预定书籍有误,西游记。equals(book5。getName()));}
  (5)异常验证Test(expectedRuntimeException。class)publicvoidexceptionTest(){ListmockedListmock(List。class);doThrow(newRuntimeException())。when(mockedList)。add(1);验证通过mockedList。add(1);}

8年过去,跑男8位老成员各奔东西,如今差距一目了然2014年,浙江台从韩国SBS引进了一档明星户外真人秀节目奔跑吧兄弟(韩版为RunningMan),用于接档中国好声音第三季。奔跑吧兄弟(以下简称跑男)一开播,就凭借超强的明星阵容无论是出差还是旅行,行李箱尽量准备好这4样东西,旅行更方便现在的生活越来越好,出门很方便,很多人在工作中会选择旅行,减轻工作压力。去旅行有很多好处。可以暂时缓解压力,回来继续努力。还可以看到各地不同的风土人情,也可以品尝各地不同的食物。但居家期间线上体验客舱飞行还能和虚拟乘务员对话,这家航司有点东西最近一段时间,疫情打乱了很多人的出行计划。大家越是久居家中,就越发想念可以乘着飞机远游的日子。近日,卡塔尔航空推出QVerse体验网站,正式入户元宇宙,让旅客即使在居家期间,也可通新改革!NBA重新设计季后赛六大奖杯新增东西部决赛MVP奖杯5月13日,NBA联盟官方宣布,联合艺术家VictorSolomon和TiffanyCo。重新设计了季后赛六大奖杯,分别是总冠军拉里奥布莱恩杯总决赛MVP比尔拉塞尔杯东部冠军鲍勃库家中有老人,一定要备好这几样东西,以防不时之需前言在我们的生活当中,有很多时候都是没有充分的准备才会出现问题。其实掌握正确的生活技巧,然后有心思才是最关键的。如果没有任何准备的话,家中有老人的一定会有很大的麻烦,因为生活并不能缅甸将于周日5月15日开始恢复签发旅游电子签证仰光(新华社)缅甸将从周日(5月15日)开始恢复接受旅游电子签证申请,这是该国因Covid19大流行而暂停所有新的电子签证申请两年多之后。缅甸移民和人口部周四表示我们的在线电子签证60岁之后,坚持做这三件事情,多半都会长寿前言60岁之后,我们的生活不简单,不要把所有的事情都想得那么复杂,一定要坚持自己该做的事情,如果生活当中自己没有任何计划的话,生活就不容易,人生也会出现问题。其实每个人都有自己的生夏日短袖避雷指南穿错一次,都会嫌弃自己在夏天的衣服中,短袖自然是占据C位的,无论是在哪一个地方,看到的比较多的就是各种短袖的穿搭示范。今天我们就来说一说,什么样的短袖是最适合男生买的。首先,请对这一种色彩满满的扎染材质广东队完成重要签约,有利王朝重建!朱芳雨获重任,重组豪阵在望导读在过往一个赛季,11冠王广东男篮走下了总冠军的神坛,虽然部分球迷叫嚷着杜锋教练必须为此负责的话语,但很明显球队的失利,并非是主教练的失职,最主要的还是球队阵容的不整以及伤病满营vivoX80Pro天玑9000版体验全能均衡的影像旗舰4月25日,vivo举行新品发布会,推出了新一代X系列旗舰vivoX80系列手机,这是vivo在4月推出的第三款旗舰手机。其中,vivoX80标准版搭载联发科4nm旗舰芯片天玑90汤普森鲁尼应该叫奥拉朱旺勇士主场11096击败灰熊,4比2晋级西部决赛。汤普森三分14投8中得到30分8篮板3帽。赛后汤普森说我喜欢这样的时刻,我喜欢压力。我们的职业生涯,我们不是歌手或者演员,我们吃的是
郭进拴两次游骊山郭进拴两次游骊山我曾于1995年和2012年两次登游骊山。骊山位于西安市临潼县境内,属秦岭支脉,海拔1200多米。据说,此山的形状很像一匹青色的骏马,古人称青色的骏马为骊,此为骊山生活中预防感冒的妙招1热水泡脚,常泡常好。脚部上有连接身体里各个部位的经络,是人体的第二心脏。因此,脚暖和了身体自然也就暖和了。在泡脚时应选择舒适的温水,泡1520分钟即可。如果方便在泡脚的同时再对脚长期吸烟的人,突然把烟戒了,是好事还是坏事?建议了解下吸烟有害健康,这是人尽皆知的一件事,尽管每个烟盒上都印有这6个醒目的警告语,但真正因此戒掉香烟的人却少之又少,长期吸食香烟严重影响健康,也会增加肺部的负担和压力,增加身体致癌的风险一个中成药,祛痰清热运脾宣肺行津调气,能化上中下三焦之痰最近有个患者来找我看病,说自己总感觉嗓子不舒服,老是有黏痰,吐也吐不出来,嗓子发痒,不停想咳嗽,偶尔吐出来一点,都是那种黏稠的黄痰。详细一问,患者还有心情烦闷头晕头昏胸膈痞满心悸失关注心率的跑者,选这块运动手表就对了在上一篇文章中PolarPacerPro会成博能最畅销的型号吗?,全面介绍的PolarPacerPro的配置和功能,那么在本篇文章重点对数据进行测评。1心率测试大家知道,polar喜欢把辛苦了挂在嘴边的,往往是这三种人你有没有发现?同样是看到他人的付出,有的人喜欢说一句辛苦了,有的人却对此无动于衷。同样是收获他人的好意,有的人愿意说一句谢谢你,有的人却认为理所应当。面对棘手的难题,有的人能够安慰性能野兽,狂飙出笼!BlueStacks蓝叠5中国区震撼发布喜欢大屏沉浸式游戏体验的玩家,一定注意到去年蓝叠海外推出BlueStacks蓝叠5时的轰动,由于其强大的性能,内测期间被媒体及粉丝奉为性能野兽,正式上线后引来了一众游戏及IT达人的煮熟的鸭子又飞了!国少女排憾负日本,给周日中日女排之战提个醒昨晚,女排亚少赛决赛场,国少女排在大比分20领先第三局又是1812大比分领先眼看胜利在望的时候,却被日本女排少年队连扳三局上演大逆转,眼睁睁地痛失冠军!看到这场失利,不由地又让人想浅谈中国女排随着世界女排联赛的开打,中国女排再次回到大众的视野。以首站三胜一负的成绩结束,明晚将开启第二站的比赛,不知道蔡指导会作何调整,作何准备。我们还是很期待的。前段时间,回答了一个问题中从小被禁止吃糖的孩子,与那些不被限制的娃,长大后差距明显孩子们对糖的喜欢与生俱来,但家长却常常视糖为洪水猛兽。很多家长为孩子健康着想,从小就控制孩子吃甜食,不仅从不主动给娃买糖吃,看到孩子吃糖还会命令禁止,也不让亲朋好友给娃吃糖。然而,通便水果排行榜,香蕉仅排第五!孩子吃了,通便更顺畅都说十娃九便秘,身边不少孩子都存在拉屎困难的情况。要么几天拉一次,要么一次一小时拉出来的便便还都呈干硬装,疼的孩子坐在马桶上哇哇直哭。无论大人还是孩子,容易便秘的最关键原因就是膳食
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网