Problems in unit testing and integration testing and some tips available

Source: Internet
Author: User

1, when it comes to the test of HTTP sending request, and the interface you want to access is not ready, you need to use Mockserver:
When there are multiple test cases in a test class, you must use static. Test found that the test class does not use static fields, each test case execution will create a new object, there will be a port creation exception, even if the use of Mockserver.stop, when the get,post are tested, there will also be returned empty (port conflict)

Pom file <dependency> <groupId>org.mock-server</groupId> <artifactid>mockserver-netty</ artifactid> <version>3.10.1</version></dependency>import Static Org.mockserver.integration.clientandserver.startclientandserver;import Static Org.mockserver.model.httprequest.request;import Static Org.mockserver.model.httpresponse.response;import Org.mockserver.integration.clientandserver;import Org.mockserver.model.header;import org.mockserver.model.httprequest;//Analog Access address is: localhost:1002 (port itself specified) Clientandserver mockserver = Startclientandserver (1002);//Prevent Cache Settings Mockserver.reset ();//Set expected return result string expected = "{\" success\ ": false,\" Message\ ": \" Success\ "}";//Request: Request method, request address (additional parameters can be added) HttpRequest ask = Request (). Withmethod ("POST"). Withpath ("/test" ); Header Header = new Header ("Content-type", "application/json;charset=utf-8"); Mockserver.when (Request) Respond (response (). Withstatuscode (200)//indicates a successful response. Withbody (expected)//response body is PeriodWithheader (header)); Format and encoding of response data

The result that is returned when the address is accessed is the value that is expected to be set.

2. Some classes, when calling a method, want to return the data they want, and can use a mock:

import static org.mockito.Matchers.any;import static org.mockito.Mockito.doThrow;import static org.mockito.Mockito.mock;import static org.mockito.Mockito.reset;import static org.mockito.Mockito.when;eg:XxService  abc = mock(XxService.class);//  1、想让该实例调用方法时返回想要的结果UserService userService = mock(UserServiceImpl.class);when(userService.getCurUser()).thenReturn(user);///2、想让调用方法时抛出指定异常RedisUtil util = mock(RedisUtil.class);doThrow(Exception.class).when(util).publish(anyString(), anyString());<!— any()表示调用方法的入参可以填任意值 —>

Then, by reflection, the mock object is set to the specified position, and when executed to the specified position, the object invocation is the mock object, and the return result of the call is the return result of the Thenreturn.

Class<CustomerServiceImpl> cla = CustomerServiceImpl.class;Constructor<CustomerServiceImpl> cfon = cla.getConstructor();CustomerServiceImpl obj = cfon.newInstance();// Field field = cla.getDeclaredField("redisUtil");field.setAccessible(true);field.set(obj, util);// 通过反射调用方法Method method = cla.getMethod("setCustomerExtraData", Customer.class);boolean result = (boolean) method.invoke(obj, customer);// 保证mock的对象重新设置回原来的对象,不然后继操作会受到影响reset(userService);

Note: If there are other auto-injected objects in the method being tested, it is also necessary to automatically inject them in the test class. They are then set in by reflection, otherwise they will not be read!
Some areas that are difficult to cover can be tested by reflection.

3, when testing the DAO layer, can use Dbunit, mainly used for pre-test data preparation, as well as the test after the expected value comparison:

// pom文件引入<dependency><groupId>com.github.springtestdbunit</groupId><artifactId>spring-test-dbunit</artifactId><version>1.3.0</version><scope>test</scope></dependency><dependency><groupId>org.dbunit</groupId><artifactId>dbunit</artifactId><version>2.5.3</version><scope>test</scope></dependency>// 类的监听@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class,DbUnitTestExecutionListener.class })@DbUnitConfiguration(dataSetLoader= XmlDataSetLoader.class)

Prepare data @DatabaseSetup (type = Databaseoperation.insert,value = "Classpath:/data/consumer.xml") Add the required data to the Consumer.xml file under data in the following format:

Prepare data <?xml version= "1.0" encoding= "UTF-8"? ><dataset><tb_consumer id= "[NULL]" name= "Junit_consumer" Type= "2" address= "junit_address" contact_number= "" "state=" 1 "create_time=" [Now] "create_user_id=" c0dc744d3aee11e892cb0025901bf22a "/><tb_consumer id=" [UUID] "name=" Junit_consumer2 "type=" 2 "address=" [NULL] " Contact_number= "state=" 1 "create_time=" [Now] "create_user_id=" c0dc744d3aee11e892cb0025901bf22a "/><tb_ Consumer id= "[UUID]" name= "Junit_consumer2" type= "[NULL]" address= "junit_address" contact_number= "[]" state= "1" Create_time= "[Now]" create_user_id= "c0dc744d3aee11e892cb0025901bf22a"/><tb_consumer id= "[UUID]" name= "Junit _consumer2 "type=" 2 "address=" junit_address "contact_number=" "state=" 1 "create_time=" [Now] "create_user_id=" c0dc744d3aee11e892cb0025901bf22a "/><tb_consumer id=" [UUID] "name=" Junit_consumer2 "type=" 2 "address=" Junit_ Address "contact_number=" "state=" 1 "create_time=" [Now] "create_user_id=" c0dc744d3aee11e892cb0025901bf22A "/></dataset> 

The node under the DataSet node is the table name. You can write to multiple tables, the fields of the table, with the [] field placeholder [UUID] to 32-bit uuid,[now] to the current time, and [null] to NULL.

// 期望@ExpectedDatabase(table = "tb_consumer",query="select * from tb_consumer where name like ‘Junit%‘", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED , value = "data/consumerExpect.xml")

Expect the file query to compare the expected file with the data in the database, if not filled will be compared with all the data in the database, table is the name, value for the desired file, fill in the expected data, when Assertionmode = Databaseassertionmode.non _strict_unordered, fields that are not filled in will not be compared

// 期望数据<?xml version="1.0" encoding="UTF-8"?><dataset><tb_consumer name="Junit_consumer2" type="2" address="[NULL]"contact_number="120" state="1" create_user_id="c0dc744d3aee11e892cb0025901bf22a" /><tb_consumer name="Junit_consumer" type="2" address="Junit_address"contact_number="110" state="1" create_user_id="c0dc744d3aee11e892cb0025901bf22a" /><tb_consumer name="Junit_consumer2" type="[NULL]" address="Junit_address"contact_number="130" state="1" create_user_id="c0dc744d3aee11e892cb0025901bf22a" /><tb_consumer name="Junit_consumer2" type="2" address="Junit_address"contact_number="140" state="1" create_user_id="c0dc744d3aee11e892cb0025901bf22a" /><tb_consumer name="Junit_consumer2" type="2" address="Junit_address"contact_number="150" state="1" create_user_id="c0dc744d3aee11e892cb0025901bf22a" /></dataset>

@Transactional a thing tag, when the method executes, the data in the database is rolled back, without affecting the original data

@SpringBootTest@RunWith(SpringJUnit4Cla***unner.class)@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,  DirtiesContextTestExecutionListener.class,  TransactionalTestExecutionListener.class,  DbUnitTestExecutionListener.class })@DbUnitConfiguration(dataSetLoader= XmlDataSetLoader.class)public class ConsumerMapperDbUnitTest {  @Autowired  private ConsumerMapper consumerMapper;  @Test  @Transactional(rollbackFor = Exception.class)  @DatabaseSetup(type = DatabaseOperation.INSERT, value = "data/consumer.xml")  @ExpectedDatabase(table = "tb_consumer", query = "select * from tb_consumer where name like ‘Junit%‘", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED,  value = "data/consumerExpect.xml")  public void testInsert() {    List<Consumer> list = consumerMapper.selectAll();    assertNotEquals(list.size(), 0);  }}

Problems in unit testing and integration testing and some tips available

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.