Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
΢·þÎñ¼Ü¹¹Ïµ¥Ôª²âÊÔÂäµØÊµ¼ù(ÏÂ)
 
×÷Õߣº¸ßÏþÅô
  2608  次浏览      27
 2021-8-20
 
±à¼­ÍƼö:
±¾ÎÄÕÂÖ÷ÒªÕë¶ÔÏîÄ¿ÖÐÉæ¼°µ½µÄµ¥Ôª²âÊԵij¡¾°½øÐдúÂëÑÝʾ£¬Ê×ÏÈ´Ó¸ÅÄºËÐÄAPIºÍ×¢½â£¬ÈçºÎʹÓöÔPowerMock¿ò¼Ü½øÐнéÉÜ¡£
±¾ÎÄÀ´×ÔÓÚºù«APP֪ʶÖÐÐÄ£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­¡¢ÍƼö¡£

ÉÏÆª½éÉÜÁ˵¥Ôª²âÊÔµÄÏà¹Ø¸ÅÄîÒÔ¼°Î¢·þÎñ¼Ü¹¹Ïµ¥Ôª²âÊÔµÄmock¿ò¼ÜµÄÑ¡ÐÍ£¬¸ÃƪÖ÷ÒªÕë¶ÔÏîÄ¿ÖÐÉæ¼°µ½µÄµ¥Ôª²âÊԵij¡¾°½øÐдúÂëÑÝʾ£¬Ê×ÏȶÔʹÓõÄPowerMock¿ò¼Ü½øÐмòµ¥µÄ½éÉÜ¡£

΢·þÎñ¼Ü¹¹Ïµ¥Ôª²âÊÔÂäµØÊµ¼ù(ÉÏ)(µã»÷²é¿´)

Ò»¡¢PowerMock¼ò½é

1.¸ÅÄî

MockitoÊÇJavaÁ÷ÐеÄÒ»ÖÖMock¿ò¼Ü£¬Mock¼¼ÊõµÄʹÓÿÉÒÔÈÃÎÒÃǵ¥Ôª²âÊÔ¸ôÀëÍⲿÒÀÀµ£¬Ãâ³ýÁ˸´ÔÓÍⲿÒÀÀµµÄ¹¹½¨¹¤×÷£¬Ê¹µÃµ¥Ôª²âÊÔ¸ü¼ÓÈÝÒ×½øÐС£Æä¹¤×÷Ô­ÀíÊÇ´´½¨ÒÀÀµ¶ÔÏóµÄÒ»¸öProxy¶ÔÏ󣬵÷ÓÃʱ£¬¶ÔÒÀÀµ¶ÔÏóµÄµ÷Óö¼ÊǾ­¹ýProxy¶ÔÏó£¬Proxy¶ÔÏóÀ¹½ØÁËËùÓеÄÇëÇó£¬Ö»Êǰ´ÕÕÔ¤ÉèÖµ·µ»Ø¡£µ«ÊÇMockitoÔÚµ¥Ôª²âÊÔʱ£¬ÓÐһЩ³¡¾°ÎÞ·¨½â¾ö£¬Ëü²»Ìṩ¶Ô¾²Ì¬·½·¨¡¢¹¹Ôì·½·¨¡¢Ë½Óз½·¨ÒÔ¼° Final ·½·¨µÄÄ£ÄâÖ§³Ö£¬ÕâÀï¾ÍÐèÒªPowerMockÁË£¬Òò´Ë¿ÉÒÔ°ÑPowerMockÀí½âΪMockitoµÄÔöÇ¿£¬Ëü½â¾öÁËMockitoһЩ²»Äܽâ¾öµÄ³¡¾°¡£

2.ºËÐÄAPIºÍ×¢½â

A a = PowerMockito.mock (A.Class)
PowerMockito.when(a.method()).thenReturn (obj)

ÉÏÃæÁ½ÐдúÂëÃèÊöÁËʹÓÃPowerMockµÄ»ù±¾Á÷³Ì£¬µÚÒ»ÐдúÂë±íʾ´´½¨ÁËAµÄÒ»¸öÐéÄâ¶ÔÏóa£»µÚ¶þÐÐÖ¸¶¨ÁËÕâ¸öÐéÄâ¶ÔÏóµÄÒ»¸öÐÐΪ£¬ÔÚµ÷ÓÃaµÄmethod()·½·¨Ê±£¬·µ»ØÁËÒ»¸öobj¶ÔÏó¡£ÕâÁ½ÐдúÂëÍê³ÉÁËÍⲿÒÀÀµµÄÄ£Äâ¹ý³Ì¡£

@Mock£º
´´½¨Ò»¸öÐéÄâ¶ÔÏó
@InjectMocks£º
´´½¨Ò»¸öʵÀý£¬ÆäÓàÓÃ@Mock£¨»ò@Spy£©
×¢½â´´½¨µÄ¶ÔÏ󽫱»×¢Èëµ½ÓøÃʵÀýÖÐ

ÕâÁ½¸öºËÐÄ×¢½âÓÃÀ´ÔÚµ¥Ôª²âÊÔÀàÖй¹½¨ÀàµÄÒÀÀµ¹ØÏµ£¬²»ÐèÒªÒÀÀµspring»·¾³£¬Ê¹µÃµ¥Ôª²âÊÔ¸üÇáÁ¿¼¶£¬ÕâÔÚºóÃæµÄʾÀý´úÂëÖлáÓÐÌåÏÖ¡£

3. ʹÓÃ

PowerMockµÄʹÓúܼòµ¥£¬Ö±½ÓÔÚpomÖÐÒýÈëÏàÓ¦µÄÒÀÀµ¼´¿É£¬ÐèҪעÒâµÄÒ»µã£¬ÓÉÓÚPowerMockÒÀÀµMockito£¬Òò´ËÁ½ÕßÒÀÀµÐèҪͬʱÒýÈ룬ÇÒÁ½Õß°æ±¾ÓÐÑϸñµÄ¶ÔÓ¦¹ØÏµ£¬Ó¦µ±°´ÕÕ¹Ù·½Ö¸¶¨µÄ°æ±¾ÒÀÀµ¹ØÏµ²ÅÄܱ£Ö¤Õý³£Ê¹Óá£ÕâÀïÊÇ»ùÓÚmockito 2.8.9ºÍpowermock 1.7.4¡£

<properties>
<mockito.version>2.8.9</mockito.version>
<powermock.version>1.7.4</powermock.version>
<properties/>

<dependencies>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependencies/>

¶þ¡¢PowerMockµ¥Ôª²âÊÔ³¡¾°

ÒÔÏÂÄÚÈÝΪÎÒÃÇÏîÄ¿Öе¥Ôª²âÊÔ¿ÉÄÜÓöµ½µÄ³¡¾°£¬PowerMock¶¼¿ÉÒÔÍê³É²âÊÔ¡£

1. dao½Ó¿ÚÄ£Äâ

@Service
public class ConsumerService {

@Autowired
private ConsumerMapper consumerMapper;

public String helloDB(String name){
System.out.println("µ÷ÓÃÊý¾Ý¿âǰµÄÒµÎñÂß¼­¡­¡­");
String result = consumerMapper.callDB(name);
System.out.println("µ÷ÓÃÊý¾Ý¿âºóµÄÒµÎñÂß¼­¡­¡­");
return result;
}
}

@Mapper
public interface ConsumerMapper {
String callDB(String name)£»
}

µ¥Ôª²âÊÔÀàÈçÏ£¬¸Ã²âÊÔÀ༰ºóÐøµÄʾÀýÖÐֻչʾ¶ÔÓ¦ÇéÐÎÏÂËùÐèҪעÈëµÄÀàºÍÒÀÀµ£º

// @RunWith±íÃ÷µ±Ç°µ¥Ôª²âÊÔÀàʹÓÃPowerMock¿ò¼Ü
@RunWith(PowerMockRunner.class)
public class PowerMockDaoTest {

// ´´½¨Ò»¸öconsumerService
@InjectMocks
ConsumerService consumerService;

// ´´½¨Ò»¸öÐéÄâµÄconsumerMapper£¬
²¢ÇÒÔÚÏÂÃæsetup·½·¨ºó»á×Ô¶¯×¢Èëµ½consumerServiceÖÐ
@Mock
ConsumerMapper consumerMapper;

@Before
public void setup(){
// ¸ù¾ÝÀàµÄ²»Í¬×¢½â£¬´´½¨²»Í¬µÄmock¶ÔÏó£¬
ͬʱÍê³É×°Å乤×÷£¬¼´Õû¸öµ¥Ôª²âÊԵijõʼ»¯
MockitoAnnotations.initMocks(this);
}

@Test
public void test() {
String name = "hulu";
// Ö¸¶¨ÐéÄâµÄµÄconsumerMapperµÄÐÐΪ,
µ÷ÓÃcallDB("hulu")ʱ£¬·µ»Øhello hulu, this is DB
PowerMockito.when (consumerMapper.callDB(name)).thenReturn ("hello hulu, this is DB");
// µ÷ÓÃservice·½·¨
String result = consumerService.helloDB (name);
//×îºóÕâÀï¼ÓÉ϶ÏÑÔ£¬½øÐÐÅжÏÖ´Ðнá¹ûÊÇ·ñ´ïµ½ÎÒÃǵÄÔ¤ÆÚ
Assert.assertEquals ("hello hulu, this is DB",result);
}
}

ÒÔÉÏÊǾ­³£ÐèÒªmockµÄÒ»ÖÖÇé¿ö£¬serviceÖе÷ÓÃÁËdao½Ó¿Ú£¬Ê¹ÓÃmockºó£¬¿ÉÒÔÔÚµ÷ÓÃdao½Ó¿Ú·½·¨Ê±£¬Èø÷½·¨°´ÕÕÎÒÃÇÖ¸¶¨µÄÈë²Î·µ»ØÖ¸¶¨µÄ·µ»ØÖµ£¬Õâ¸ö¹ý³Ì²»ÐèÒªÕæÊµÁ¬½ÓÊý¾Ý¿â£¬ÊµÏÖÆÁ±ÎÊý¾Ý¿âµÄµÚÈý·½ÒÀÀµ¡£

ÉÏͼչʾÁËÕæÊµµ÷Óùý³ÌÖÐÖ´Ðе½callDB("hulu")ʱ£¬consumerMapperµÄÕæÊµ×´Ì¬£¬¿ÉÒÔ¿´µ½ÒѾ­±ä³ÉÁËMock¿ò¼ÜÉú³ÉµÄ´úÀí¶ÔÏ󣬴úÀí¶ÔÏóÔÚÖ´ÐÐÏàÓ¦·½·¨Ê±£¬°´ÕÕÖ¸¶¨µÄÔ¤ÆÚÖµ½øÐÐÁË·µ»Ø¡£

2. feignÔ¶³Ìµ÷ÓÃÄ£Äâ

ÏÂÃæÊÇ΢·þÎñÖУ¬Ê¹ÓÃfeignµ÷ÓÃÔ¶³Ì·þÎñµÄʾÀý´úÂ룺

@Service
public class ConsumerService {

@Autowired
HelloRemote helloRemote;
// ͨ¹ýhelloRemoteÔ¶³Ìµ÷ÓÃµÄÆäËû·þÎñ
public String helloRemote (@PathVariable("name") String name) {
System.out.println ("ÆäËûÒµÎñÂß¼­");
String hello = helloRemote.hello(name);
System.out.println ("ÆäËûÒµÎñÂß¼­");
return hello;
}
}

@FeignClient
(name="service-producer",fallback=HelloRemoteFallback.class)
public interface HelloRemote {
@RequestMapping (value="/hello")
String hello (@RequestParam(value = "name") String name);
}

µ¥Ôª²âÊÔʾÀýÈçÏ£¬ºÍÉÏÊöµÄÆÁ±ÎÊý¾Ý¿âÒÀÀµÀàËÆ£º

@RunWith (PowerMockRunner.class)
public class PowerMockFeignTest {

@InjectMocks
ConsumerService consumerService;

@Mock
HelloRemote helloRemote;

@Before
public void setup(){
MockitoAnnotations.initMocks (this);
}

@Test
public void test() {
String name = "hulu";
String mockResult = "hello hulu, this is fallback";
// Ö¸¶¨µ÷ÓÃÔ¶¶Ë·þÎñ½Ó¿Úʱ·µ»ØÔ¤ÆÚÖµ
PowerMockito.when (helloRemote.hello(name)).thenReturn (mockResult);
// µ÷ÓÃservice·½·¨
String result = consumerService.helloRemote (name);
//ÅжÏÖ´Ðнá¹ûÊÇ·ñ´ïµ½ÎÒÃǵÄÔ¤ÆÚ
Assert.assertEquals (mockResult,result);
}

}

ͬÑùÉÏÊöµÄÔ¶³Ì·þÎñµ÷Óò¢²»ÐèÒªÔ¶³Ì·þÎñÕæÊµ¿ÉÓã¬Ê¹Óÿò¼ÜÖ¸¶¨Á˵÷Ó÷½·¨µÄ·µ»ØÖµ£¬·½·¨¾Í¿ÉÒÔ°´ÕÕÔ¤ÆÚÖµ·µ»Ø£¬±£Ö¤Õâ¸ö·½·¨²»ÒÀÀµÔ¶³Ì·þÎñ¼´¿ÉÍê³Éµ¥Ôª²âÊÔ¡£

3. redisµ÷ÓÃÄ£Äâ

·Ö²¼Ê½ÏµÍ³ÖÐredisÊÇ×î³£ÓõÄÖÐÑ뻺´æ£¬ÒÔÏÂÊǶÔredisµÄmock¹ý³Ì¡£Ê¾Àý´úÂëÈçÏ£º

@Service
public class ConsumerService {
// ÕâÀïÖ±½ÓʹÓÃredisTemplate²Ù×÷redis£¬
ʵ¼ÊÏîÄ¿ÖпÉÄÜ»áÔÙ·â×°Ò»²ã
@Autowired
private RedisTemplate<String, String> redisTemplate;

public String helloRedis(String key){
System.out.println("µ÷ÓÃredisǰµÄÒµÎñÂß¼­¡­¡­");
String result = redisTemplate.opsForValue().get(key);
System.out.println ("µ÷ÓÃredisºóµÄÒµÎñÂß¼­¡­¡­");
return result;
}
}

@RunWith(PowerMockRunner.class)
public class RedisTest {

@InjectMocks
ConsumerService consumerService;

@Mock
private RedisTemplate<String, String> redisTemplate;

@Before
public void setup(){
// Õâ¾ä»°Ö´ÐÐÒÔºó£¬redisTemplate×Ô¶¯×¢Èëµ½consumerServiceÖÐ
MockitoAnnotations.initMocks(this);
}

@Test
public void test() {
String key = "test";
// ¶ÔredisTemplate.opsForValue().get("key")
½øÐÐmock ÕâÒ²ÊÇÒ»¸ö¼¶Áª·½·¨µÄmock
ValueOperations valueOperations = PowerMockito.mock (ValueOperations.class);
PowerMockito.when (redisTemplate.opsForValue()).thenReturn (valueOperations);
PowerMockito.when (valueOperations.get ("test")).thenReturn ("this is mock redis");
// µ÷ÓÃservice·½·¨
String result = consumerService.helloRedis (key);
// ÅжÏÖ´Ðнá¹ûÊÇ·ñ´ïµ½ÎÒÃǵÄÔ¤ÆÚ
Assert.assertEquals ("this is mock redis",result);
}
}

ÉÏÊöʾÀýµÄÌØÊâÖ®´¦ÔÚÓÚµ÷Óõķ½·¨ÊÇÒ»¸ö¼¶Áª·½·¨redisTemplate.opsForValue().get(key); ¶ÔÕâÀàµ÷ÓõÄmockÐèÒª·Ö²½½øÐУ¬¼´ÏÈÖ¸¶¨redisTemplate.opsForValue()µÄ·µ»ØÖµ£¬È»ºóÔÙÖ¸¶¨Æä·µ»ØÖµget(key)µÄ·µ»ØÖµ£¬Íê³ÉÒ»¸ö¼¶Áª·½·¨µÄÄ£Äâ¡£

4. kafkaµ÷ÓõÄÄ£Äâ

ÏîÄ¿ÖÐʹÓÃÁËkafka£¬ÊµÏÖÁ˶ÔkafkaÉú²úÕߺÍÏû·ÑÕßµÄÄ£Ä⡣ʾÀý´úÂëÈçÏ£º

@Service
public class ConsumerService {

@Autowired
private KafkaTemplate kafkaTemplate;

/**
* Éú²úÕß
*/
public String sendMessage (String topic,String value){
System.out.println ("Ïòkafka·¢ËÍÏûϢǰִÐеÄÂß¼­");
ListenableFuture send = kafkaTemplate.send (topic, value);
System.out.println ("Ïòkafka·¢ËÍÏûÏ¢ºóÖ´ÐеÄÂß¼­");
return "success";
}

/**
* Ïû·ÑÕß
*/
@KafkaListener(topics = {"${kafka.consumer.topic}"})
public void consumeMessage (ConsumerRecord<?, ?> record) throws IOException {
String value = (String) record.value();
System.out.println ("µ±Ç°»ñÈ¡µÄÏûÏ¢ÄÚÈÝΪ£º"+value);
System.out.println ("ʹÓÃÏûÏ¢Ö´ÐÐÁËһЩÂß¼­");
}
}

@RunWith (PowerMockRunner.class)
@PrepareForTest({ConsumerRecord.class})
public class KafkaTest {

@InjectMocks
ConsumerService consumerService;

@Mock
private KafkaTemplate kafkaTemplate;

@Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
/**
* Éú²úÕß²âÊÔ
*/
@Test
public void testSend() {
String topic = "result";
String value = "ÕâÊÇÒ»Ìõ²âÊÔµÄÏûÏ¢";
// Ê×ÏÈÖ¸¶¨mock send·½·¨µÄ·µ»ØÖµ
ListenableFuture mockFuture = PowerMockito.mock (ListenableFuture.class);
// Ö¸¶¨send·½·¨µ÷ÓÃʱºòµÄ¶¯×÷
PowerMockito.when(kafkaTemplate.send (topic,value)).thenReturn(mockFuture);
String result = consumerService.sendMessage (topic,value);
Assert.assertEquals ("success",result);
}
/**
* Ïû·ÑÕß²âÊÔ
*/
@Test
public void testConsume() throws IOException {
ConsumerRecord mockRecord = PowerMockito.mock (ConsumerRecord.class);
PowerMockito.when ((String)mockRecord.value()).thenReturn ("value");
consumerService.consumeMessage (mockRecord);
}
}

@PrepareForTest({ConsumerRecord.class})£¬ÕâÀï¼òҪ˵Ã÷Ò»ÏÂËüµÄ×÷Ó㺵±mockÒ»Ð©ÌØÊâ·½·¨Ê±£¬Èçstatic£¬final£¬private£¬ÏµÍ³Ààstatic·½·¨Ê±£¬ÕâЩ·½·¨ËùÔÚµÄÀàÐèÒªÔÚ@PrepareForTestÀïÖ¸Ã÷£¬·ñÔò»á±¨²»ÄÜmock¸ÃÀàµÄÒì³££º

org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class org.apache.kafka.clients.consumer.ConsumerRecord.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.

MockitoÎÞ·¨Ä£ÄâÒ»¸öConsumerRecord£¬ÒòΪConsumerRecordÊÇÒ»¸öfinalÀ࣬±ØÐëÔÚ×¢½âÖÐÖ¸Ã÷¡£ÕâÒ²ÊÇPowerMockÏà¶ÔÓÚMockitoµÄ¹ýÈËÖ®´¦£¬½â¾öÁËMockitoÎÞ·¨mockÌØÊâ·½·¨µÄÍ´µã£»ÁíÍ⵱ʹÓÃPowerMockito.whenNew·½·¨Ê±£¬±ØÐë¼Ó×¢½â@PrepareForTest£¬×¢½â@PrepareForTestÀïдµÄÀàÊÇÐèÒªmockµÄnew¶ÔÏó´úÂëËùÔÚµÄÀ࣬ÕâÒ»µãÔÚºóÃæ¹¹Ôì·½·¨µÄÄ£ÄâÖлáÓÐÌåÏÖ¡£

6. sessionµÄÄ£Äâ

ÏîĿʹÓÃÁËSpringSession+RedisµÄ·Ö²¼Ê½session½â¾ö·½°¸£¬Òò´Ë¾­³£ÐèÒª´ÓsessionÖлñÈ¡µ±Ç°Óû§id£¬ÓÉÓÚrequestºÍsession¶ÔÏóµÄ¸´ÔÓÐÔ£¬ÔÚÕâÀàÇéÐÎϱàдµ¥Ôª²âÊԷdz£À§ÄÑ£¬ÒòΪÎÞ·¨ÊÖ¶¯´´½¨Ò»¸ö·ûºÏÔ¤ÆÚµÄrequest»òÕßsession¶ÔÏó£¬Ê¹ÓÃmock¿ò¼Ü¿ÉÒÔÇáËɽâ¾ö¡£

@Service
public class ConsumerService {

public String getUserName (HttpServletRequest request){
// ´ÓsessionÖлñÈ¡Óû§id
String userId = (String)request.getSession().getAttribute ("userId");
System.out.println("ÕâÀﻹִÐÐÁËһЩÆäËûÂß¼­");
// ¼ÙÉè¸ù¾ÝÓû§id²éѯÁËÊý¾Ý¿â
String userName = consumerMapper.callDB (userId);
// ·µ»ØÓû§ÐÕÃû
return userName;
}
}

ÉÏÊö´úÂëÃèÊöÁËÒ»¸ö³£¼û³¡¾°£¬´ÓsessionÖлñÈ¡Óû§id£¬²¢¸ù¾ÝÓû§id²éѯÊý¾Ý¿â»ñÈ¡Óû§ÐÅÏ¢µÄʾÀý¡£µ¥Ôª²âÊÔ´úÂëÈçÏ£º

@RunWith (PowerMockRunner.class)
public class SessionTest {

@InjectMocks
ConsumerService consumerService;

@Mock
ConsumerMapper consumerMapper;

@Before
public void setup() {
MockitoAnnotations.initMocks (this);
}

@Test
public void test() {
// mock HttpServletRequest
HttpServletRequest mockRequest = PowerMockito.mock (HttpServletRequest.class);
// mock HttpSession
HttpSession mockSession = PowerMockito.mock (HttpSession.class);
// Ö¸¶¨ÁËrequestµ÷ÓÃgetSessionʱ·µ»ØmockSession
PowerMockito.when (mockRequest.getSession()).thenReturn(mockSession);
// Ö¸¶¨session»ñÈ¡userIdʱ·µ»Ø123
PowerMockito.when (mockSession.getAttribute("userId")).thenReturn("123");
// Ö¸¶¨ÁËÓÃ123È¥²éѯÊý¾Ý¿â·µ»ØµÄÓû§zhangsan
PowerMockito.when (consumerMapper.callDB("123")).thenReturn("zhangsan");
// µ÷ÓÃservice·½·¨
String result = consumerService.getUserName (mockRequest);
//×îºóÕâÀï¼ÓÉ϶ÏÑÔ£¬½øÐÐÅжÏÖ´Ðнá¹ûÊÇ·ñ´ïµ½ÎÒÃǵÄÔ¤ÆÚ
Assert.assertEquals ("zhangsan", result);
}
}

7. controller²ãµ¥Ôª²âÊÔÄ£Äâ

ͨ³£°´ÕÕ´úÂë¹æ·¶£¬controller²ãÊDz»ÔÊÐíÓÐÒµÎñÂß¼­µÄ´æÔÚ£¬Òò´ËҲ̸²»ÉÏÐèÒª½øÐе¥Ôª²âÊÔÁË¡£µ«ÊÇÈôÓÉÓÚijЩԭÒò´æÔÚÒµÎñÂß¼­ÐèÒª½øÐе¥Ôª²âÊÔ£¬Ê¹Óÿò¼ÜÒ²ÊÇ¿ÉÒÔʵÏֵġ£Ê¾Àý´úÂëÈçÏ£º

@RestController
public class ConsumerController{

@Autowired
private ConsumerService consumerService;

@RequestMapping (value="/helloLocal/{name}")
public String helloLocal(@PathVariable ("name") String name){
System.out.println ("һЩ²»¸Ã´æÔÚµÄÒµÎñÂß¼­");
String result = consumerService.helloLocal(name);
System.out.println ("һЩ²»¸Ã´æÔÚµÄÒµÎñÂß¼­");
return result;
}
}


@RunWith(PowerMockRunner.class)
public class ControllerTest {

@Mock
private ConsumerService service;

@InjectMocks
private ConsumerController consumerController;

@Test
public void testHelloLocal(){
String name = "hulu";
// Ö¸¶¨mockservice·½·¨µÄÐÐΪ
PowerMockito.when (service.helloLocal(name)).thenReturn ("hello hulu, this is mock local");
String result = consumerController.helloLocal(name);
Assert.assertEquals ("hello hulu, this is mock local",result);
}
}

¹Û²ìÒÔÉÏ´úÂë·¢ÏÖ·½·¨ºÍÇ°ÃæµÄ²âÊÔʵÏÖ˼·һÑù£¬Ö»ÊÇÔ­À´´ý×¢ÈëµÄÀàÊÇservice£¬ÏÖÔÚ±ä³ÉÁËcontroller£¬Ä£ÄâÒ»¸öservice¶ÔÏó£¬Ö¸¶¨ÆäÐÐΪ£¬Íê³Écontroller²ãµÄµ¥Ôª²âÊÔ£¬ÑéÖ¤³ý¸ÃÐÐÍâÆäËûµÄÒµÎñÂß¼­¡£

8. ¹¹Ôì·½·¨µÄÄ£Äâ

¹¹Ôì·½·¨µÄmockÖ÷ÒªÊÇÕë¶Ô´úÂëÖÐʹÓöÔÏóµÄ¹¹Ôì·½·¨´´½¨¶ÔÏó¡£ÏÂÃæÊÇ×Ô¶¨ÒåµÄÒ»¸öʵÌ壬°üº¬ÁËÎ޲ι¹ÔìºÍÓвι¹Ôì¡£

public class NewClass {

private String message;
// Î޲ι¹Ôì
public NewClass(){}
// Óвι¹Ôì
public NewClass(String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

ÏÂÃæÊÇÒ»¸öÀàÖÐʹÓÃÁËÏàÓ¦µÄ¹¹Ôì·½·¨


public class TargetClass {

public String getMessage(){
// ʹÓÃÎ޲ι¹Ôì´´½¨ÁËÒ»¸ö¶ÔÏó
NewClass object= new NewClass();
return object.getMessage();
}

public String getInsertMessage(){
// ʹÓÃÓвι¹Ôì¹¹½¨ÁËÒ»¸ö¶ÔÏó
NewClass object= new NewClass ("this is another message");
return object.getMessage();
}
}

µ¥Ôª²âÊÔʾÀý´úÂëÈçÏÂ


@RunWith(PowerMockRunner.class)
// ÐèÒªÔÚ@PrepareForTestÖÐÖ¸Ã÷ÕâÁ½Õß
@PrepareForTest({NewClass.class,TargetClass.class})
public class NewObjectTest {

/**
* ÕâÖÖnew¶ÔÏóµÄmockÒ²¿ÉÒÔÀí½â³ÉÊÇmockÎ޲ι¹ÔìµÄ·½·¨
*/
@Test
public void testConstructionMethodWithNoArg() throws Exception {
// ÒªmockµÄnewµÄÀà
NewClass newClass = PowerMockito.mock (NewClass.class);
// ÕâÀïÊǵ±Ê¹ÓÃÎ޲ι¹Ôìʱºò·µ»ØÎÒÃÇmockµÄʵÌå
PowerMockito.whenNew (NewClass.class).withNoArguments().thenReturn (newClass);
// Ö¸¶¨µ±µ÷ÓÃmockµÄÕâ¸öʵÌåµÄ·½·¨Ê±ºò·µ»ØÖ¸¶¨µÄÖµ
String mockResult = "this is mock message";
PowerMockito.when (newClass.getMessage()).thenReturn(mockResult);
// ´´½¨ÎÒÃÇÒª²âÊÔµÄÄ¿±êÀ࣬²¢Ö´ÐÐÎÒÃǵķ½·¨
TargetClass targetClass = new TargetClass();
String message = targetClass.getMessage();
// УÑé·µ»ØÖµ
Assert.assertEquals (mockResult,message);
}

/**
* mock Óвι¹Ôì
*/
@Test
public void testConstructionMethodWithArg() throws Exception {
// ÏÈmockÒ»¸öÕâ¸öÀàµÄ¶ÔÏó
NewClass newClass = PowerMockito.mock(NewClass.class);
// ÕâÀïÊǵ±Ê¹ÓÃÓвι¹Ôìʱºò·µ»ØÎÒÃÇÖ¸¶¨µÄmock¶ÔÏó
String message = "this is another message";
PowerMockito.whenNew(NewClass.class).withArguments (message).thenReturn(newClass);
// Ö¸¶¨µ±µ÷ÓÃmock¶ÔÏóµÄ·½·¨Ê±ºòµÄ·µ»ØÖµ
String mockMessage = "this is another mock message";
PowerMockito.when (newClass.getMessage()).thenReturn (mockMessage);
// ÕâÀï´´½¨°üº¬mock¶ÔÏóµÄÀ࣬ÕâÀï½øÐз½·¨²âÊÔ
TargetClass targetClass = new TargetClass();
String returnMessage = targetClass.getInsertMessage();
// УÑé·µ»ØÖµ
Assert.assertEquals (mockMessage,returnMessage);
}
}

9. final·½·¨µÄÄ£Äâ

Ò»¸ö³ÖÓÐfinal·½·¨µÄÀࣺ

public class FinalMethodClass {

public final String finalMethod(){
return "this is finalMethod";
}
}

Ò»¸öµ÷ÓÃfinal·½·¨µÄÀࣺ


public class FinalMethodCallerClass {
// ³ÖÓÐÒ»¸ö°üº¬FinalMethodµÄ¶ÔÏó
private FinalMethodClass finalMethodClass;

public FinalMethodCallerClass (FinalMethodClass finalMethodClass) {
this.finalMethodClass = finalMethodClass;
}

public String callFinalMethod(){
return finalMethodClass.finalMethod();
}
}

²âÊÔʾÀý´úÂëÈçÏ£º


@RunWith(PowerMockRunner.class)
@PrepareForTest({FinalMethodClass.class})
// Ö¸Ã÷³ÖÓÐfinal·½·¨µÄÀà
public class FinalMethodTest {

// ʹÓÃ×¢½â¹¹½¨ÁËmock¶ÔÏ󣬺ÍÖ±½ÓʹÓÃPowerMockito.mockЧ¹ûÒ»Ñù
@Mock
private FinalMethodClass finalMethodClass;

@Test
public void testCreateUser(){
String result = "this is mock finalMethod";
// Ö¸¶¨Õâ¸ömock¶ÔÏóµ÷ÓÃij¸ö·½·¨Ê±µÄÐÐΪ
PowerMockito.when (finalMethodClass.finalMethod()).thenReturn(result);
// ½«mock¶ÔÏ󴫵ݸøµ÷Ó÷½£¬ÕâÀïͨ¹ý¹¹Ôì·½·¨
FinalMethodCallerClass callerClass = new FinalMethodCallerClass (finalMethodClass);
// µ÷ÓÃÕâ¸öµ÷Ó÷½µÄµ÷Ó÷½·¨
String mockResult = callerClass.callFinalMethod();
Assert.assertEquals (result,mockResult);
}
}

10. static·½·¨µÄÄ£Äâ

Ò»¸ö³ÖÓÐstatic·½·¨µÄÀࣺ

<table width="70%" border="0" align="center" id="ccc" cellpadding="7" cellspacing="1" bgcolor="#CCCCCC" class="content" style="text-indent: 0em;">
<tr bgcolor="#FFFFFF">
<td height="25" bgcolor="#f5f5f5">aaa
</td>
</tr>
</table>

ʾÀý´úÂëÈçÏ£º


@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticMethodClass.class)
// Ö¸Ã÷³ÖÓÐstatic·½·¨µÄÀà
public class StaticMethodTest {

@Test
public void test(){
// ºÍÇ°ÃæµÄÇø±ð£¬Ê¹ÓÃmockStatic·½·¨
PowerMockito.mockStatic (StaticMethodClass.class);
// Ö¸¶¨static·½·¨·µ»ØÎÒÃÇÔ¤ÆÚÖµ
PowerMockito.when (StaticMethodClass.sayHello("hulu"))
.thenReturn("hello hulu, this is mock static method");
String result = StaticMethodClass.sayHello ("hulu");
Assert.assertEquals ("hello hulu, this is mock static method",result);
}
}

ÉÏÊöÌØÊâÖ®´¦ÔÚÓÚÐèÒªÔÚ@PrepareForTestÖÐÖ¸Ã÷³ÖÓÐstatic·½·¨µÄÀ࣬ͬʱÔÚ´´½¨¸ÃÀàµÄmock¶ÔÏóʱʹÓõÄÊÇmockStatic·½·¨¡£

11. private·½·¨µÄÄ£Äâ

Ò»¸ö³ÖÓÐprivate·½·¨µÄÀࣺ

public class PrivateMethodClass {

public String callPrivate() {
System.out.println ("these is other method");
return privateMehod();
}

private String privateMehod() {
return "this is private mthod";
}

}

²âÊÔʾÀý´úÂëÈçÏ£º

@RunWith (PowerMockRunner.class)
@PrepareForTest ({PrivateMethodClass.class})
public class PrivateMethodTest {

@Test
public void testMockPrivateFunc() throws Exception {
// spyÒ»¸öPrivateMethodClass spy³öÀ´µÄ¶ÔÏó¿ÉÒÔÈÏΪÊǸöÕæµÄ¶ÔÏó
PrivateMethodClass privateMethodClass = PowerMockito.spy (new PrivateMethodClass());
// Ö¸¶¨Õâ¸ö¶ÔÏóÖеÄprivate·½·¨µÄ·µ»ØÖµ
String result = "this is mock private method";
PowerMockito.when (privateMethodClass, "privateMehod").thenReturn (result);
// µ÷ÓÃÕâ¸öÕâ¸öÀàÖеĵ÷ÓÃprivate·½·¨µÄ·µ»ØÖµ
String realResult = privateMethodClass.callPrivate();
Assert.assertEquals (realResult, result);
}
}

ͬÑùÐèÒªÔÚ@PrepareForTestÖ¸¶¨³ÖÓÐprivate·½·¨µÄÀà¡£

12. ¼¶Áª·½·¨µÄÄ£Äâ

¼¶Áª·½·¨Ö¸µÄÊÇÐÎÈça.method1().method2()µÄ·½·¨£¬¹ØÓÚÕâÀà·½·¨µÄmock£¬Ë¼Â·¾ÍÊÇÒ»²ãÒ»²ã½øÐÐÄ£Ä⣬¾ßÌåÀý×Ó¿ÉÒԲο¼redis²¿·ÖºÍsession²¿·Ö£¬²Î¿¼redisTemplate.opsForValue().get(key)ºÍrequest.getSession().getAttribute("userId")µÄÄ£Äâ¡£

13. Òì³£µÄÄ£Äâ

ÒÔÏÂÀý×ÓΪģÄâµ÷ÓÃij·½·¨Ê±£¬Ä£Äâ·½·¨·µ»ØÒì³££¬¿ÉÒÔÓÃÀ´²âÊÔ´úÂëÖÐÒì³£´¦Àí»úÖÆÊÇ·ñÂú×ãÐèÇó¡£

public class ExceptionClass {

public void throwException (String name){
System.out.println("Å׳öÒì³£");
}
}

²âÊÔʾÀý´úÂëÈçÏ£º

@Test(expected = RuntimeException.class)
public void testException(){
// mockÕâ¸öÀà
ExceptionClass mock = PowerMockito.mock (ExceptionClass.class);
// mockij¸ö·½·¨ÔÚÖ¸¶¨²ÎÊýÏÂÅ׳öÒì³£
Exception e = new RuntimeException ("test");
PowerMockito.doThrow(e).when(mock).throwException ("mock");
// Ö´Ðе±Ç°Ðкó¾Í»áÅ׳öÒì³£
String result = mock.throwException ("mock");
System.out.println("Ö´Ðв»µ½µ±Ç°ÐдúÂë");
}

ÉÏÊöÃèÊömockÒì³£µÄʾÀý´úÂ룬¿ÉÒÔ¸ù¾Ýʵ¼ÊÐèÇó½øÐÐÒì³£µÄÄ£Ä⣬¼ì²â´úÂëÖÐÒì³£´¦Àí»úÖÆ¡£

14. ÄÚ²¿ÀàµÄÄ£Äâ

¶¨ÒåÒ»¸öÀàOuter£¬³ÖÓÐÁ½ÖÖÄÚ²¿À࣬·Ö±ðÊǷǾ²Ì¬ºÍ¾²Ì¬ÄÚ²¿Àà¡£

public class Outer {
// ·Ç¾²Ì¬ÄÚ²¿Àà
public class Inner2{
String s = "hello hulu, this is inner method2.";
public String innerMethod (){
System.out.println ("inner2");
return s;
}
}
// ¾²Ì¬ÄÚ²¿Àà
public static class Inner3{
static String s = "hello hulu, this is inner method3.";
public static String innerMethod(){
System.out.println ("inner3");
return s;
}
}
}

²âÊÔʾÀý´úÂëÈçÏ£º

@RunWith(PowerMockRunner.class)
@PrepareForTest({Outer.Inner3.class})
// ¾²Ì¬ÄÚ²¿ÀàÐèÒªÔÚÕâÀïÖ¸Ã÷
public class PowerMockInnerClassTest2 {
/**
* mock publicÐÞÊεķǾ²Ì¬ÄÚ²¿Àà
*/
@Test
public void InnerClassTest() {
// mock ÆÕͨ³ÉÔ±±äÁ¿ÄÚ²¿Àà
Outer.Inner2 mockInner2 = PowerMockito.mock (Outer.Inner2.class);
PowerMockito.when (mockInner2.innerMethod()).thenReturn("this is mock inner method2.");
String result = mockInner2.innerMethod();
Assert.assertEquals ("this is mock inner method2.",result);
}
/**
* mock publicÐÞÊεľ²Ì¬ÄÚ²¿Àà
*/
@Test
public void InnerClassTest2() {
// mock static µÄÄÚ²¿Àà
PowerMockito.mockStatic(Outer.Inner3.class);
PowerMockito.when (Outer.Inner3.innerMethod()).thenReturn ("this is mock inner method3.");
String result = Outer.Inner3.innerMethod ();
Assert.assertEquals ("this is mock inner method3.",result);
}
}

15. µ¥ÀýµÄÄ£Äâ

ÕâÀïʹÓõ¥ÀýģʽµÄ×îºÃʵ¼ù£¬¾²Ì¬ÄÚ²¿ÀàµÄµ¥Àý£¬ÀÁ¼ÓÔØ£¬²¢ÇÒµ¥ÀýÓÃÀà¼ÓÔØ»úÖÆ±£Ö¤£¬Ḭ̈߳²È«¡£´úÂëÈçÏ£º

public class Singleton {

private Singleton (){};

public String printHelloWorld ( String value ) {
StringBuilder stringBuilder = new StringBuilder ( "name is: " );
return stringBuilder.append ( value ).toString();
}

/**
* ÄÚ²¿Àà³ÖÓÐÍⲿÀàµÄÒ»¸ö¶ÔÏó£¬Àà¼ÓÔØÊ±ºò²»»á³õʼ»¯£¬Ö»ÓÐÕæÕý±»µ÷ÓÃʱºò²Å»á±»³õʼ»¯
*/
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton ();
}

public static Singleton getInstance () {
return SingletonInstance.INSTANCE;
}
}

´´½¨Ò»¸öµ¥ÀýÀàµÄʹÓÃÕߣ¬µ÷ÓÃÁ˵¥ÀýµÄ·½·¨£º

public class SingletonUser {

public String useSingletonMethod(){
String result = Singleton.getInstance().printHelloWorld ("hulu");
return result;
}
}

µ¥Ôª²âÊÔʾÀý´úÂëÈçÏ£º

@RunWith(PowerMockRunner.class)
@PrepareForTest(Singleton.class)
// ÌØÊâÀà ÐèҪʹÓÃÕâ¸ö×¢½â½øÐÐ×¼±¸
public class SingletonTest {

/**
* mockÒ»¸öµ¥Àý£¬²¢ÇÒÄ£Äâµ¥ÀýµÄ·½·¨·µ»ØÖµ
* @throws ClassNotFoundException
*/
@Test
public void test() throws ClassNotFoundException {
// mockÒ»¸öµ¥ÀýÀà
Singleton mockSingleton = PowerMockito.mock(Singleton.class);
// ͨ¹ý·´Éä»ñÈ¡Õâ¸öµ¥ÀýÀàÄÚ²¿µÄÄÚ²¿ÀàµÄclass¶ÔÏó
Class clazz = Whitebox.getInnerClassType(Singleton.class, "SingletonInstance");
// ͨ¹ý·´É䏸ÄÚ²¿Àà³ÖÓеÄÍⲿÀàµÄÒýÓø³ÖµÎªmock³öµÄµ¥Àý¶ÔÏó
Whitebox.setInternalState(clazz, "INSTANCE", mockSingleton);
// µ±µ÷Óõ¥ÀýÀàµÄ·½·¨Ê±ºò Ö¸¶¨Æä·µ»ØÖµ
PowerMockito.when( mockSingleton.printHelloWorld (Mockito.anyString())).thenReturn( "this is mock singleton method result" );
// ´´½¨µ¥ÀýÀàµ÷ÓÃÕß
SingletonUser singletonUser = new SingletonUser();
// µ¥ÀýÀà·½·¨µ÷ÓÃÕßµ÷Ó÷½·¨
String result = singletonUser.useSingletonMethod();
Assert.assertEquals("this is mock singleton method record",singletonUser.useSingletonMethod());
}
}

ÉÏÊö´úÂëÖÐÌØÊâÖ®´¦ÔÚÓÚ£¬³ÖÓе¥ÀýµÄÄÚ²¿ÀàÊÇprivateµÄ£¬Òò´ËÔÚ»ñÈ¡ÄÚ²¿ÀàµÄclass¶ÔÏóʱ£¬ÐèҪʹÓÃPowerMockÌṩµÄ·´É乤¾ßÀ࣬ͨ¹ý·´ÉäµÄ·½Ê½»ñÈ¡Æäclass¶ÔÏó£¬È»ºóͨ¹ý·´É䏸ÄÚ²¿ÀàµÄÊôÐÔÖ¸¶¨ÎÒÃÇmock³öµÄµ¥Àý£¬²¢ÇÒÖ¸¶¨µ¥ÀýÔÚÖ´Ðб¾ÉíprintHelloWorld()·½·¨Ê±·µ»ØÎÒÃÇÔ¤ÆÚµÄÖµ£¬½ø¶øÍê³Éµ¥Àý¶ÔÏó·½·¨µ÷ÓõÄÄ£Äâ¡£

ÉÏÊö½éÉܵij¡¾°ÆäʵÓкܶàÔÚʵ¼Êµ¥Ôª²âÊÔ¹ý³ÌÖÐÊǺÜÉÙÓöµ½µÄ£¬Í¨³£mock¿ò¼ÜʹÓÃ×î¶àµÄ³¡¾°ÊÇÇ°Ãæ½éÉܵĵÚÈý·½ÒÀÀµ¼°¸´ÔÓ¶ÔÏóµÄ³¡¾°¡£

Èý¡¢×ܽá

ÒÔÉÏչʾÁËPowerMockÈçºÎ½â¾öÏîÄ¿ÖÐһЩǿµÄµÚÈý·½ÒÀÀµ¡¢¸´ÔÓ¶ÔÏó¼°ÌØÊâ·½·¨µÈ²âÊÔ³¡¾°£ºÊ¹ÓÃmock¿ò¼Ü´´½¨ÐéÄâµÄ¶ÔÏó£¬Ö¸¶¨ÏàÓ¦¶ÔÏó·½·¨µ÷ÓÃʱµÄ·µ»ØÖµ£¬´Ó¶ø´ïµ½µ÷ÓöÔÓ¦´úÂëʱ£¬Äܹ»°´ÕÕÔ¤ÆÚ·µ»ØÖ¸¶¨Öµ£¬½ø¶ø±£Ö¤Á˲âÊÔ·½·¨ÖÐÆäËûÒµÎñÂß¼­µÄÕý³£Ö´ÐУ»ÓÉÓÚÆÁ±ÎÁËÍⲿÒÀÀµ£¬¼ò»¯Á˵¥Ôª²âÊÔËùÐèÕæÊµ»·¾³µÄÅäÖÃ,Ìá¸ßÁ˵¥Ôª²âÊÔµÄÖ´ÐÐЧÂÊ£¬ÎªÈí¼þµÄ»ù±¾×é³Éµ¥ÔªµÄÕýÈ·ÐÔÌṩÁ˱£Ö¤¡£

   
2608 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

΢·þÎñ²âÊÔÖ®µ¥Ôª²âÊÔ
һƪͼÎÄ´øÄãÁ˽â°×ºÐ²âÊÔÓÃÀýÉè¼Æ·½·¨
È«ÃæµÄÖÊÁ¿±£ÕÏÌåϵ֮»Ø¹é²âÊÔ²ßÂÔ
È˹¤ÖÇÄÜ×Ô¶¯»¯²âÊÔ̽Ë÷
Ïà¹ØÎĵµ

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
jenkins³ÖÐø¼¯³É²âÊÔ
ÐÔÄܲâÊÔÕï¶Ï·ÖÎöÓëÓÅ»¯
ÐÔÄܲâÊÔʵÀý
Ïà¹Ø¿Î³Ì

³ÖÐø¼¯³É²âÊÔ×î¼Ñʵ¼ù
×Ô¶¯»¯²âÊÔÌåϵ½¨ÉèÓë×î¼Ñʵ¼ù
²âÊԼܹ¹µÄ¹¹½¨ÓëÓ¦ÓÃʵ¼ù
DevOpsʱ´úµÄ²âÊÔ¼¼ÊõÓë×î¼Ñʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
 
×îÐÂÎÄÕÂ
´óÊý¾Ýƽ̨²âÊÔ
΢·þÎñ¼Ü¹¹ÏµIJâÊÔÖ®µÀ
´ÓÁã¿ªÊ¼ÕÆÎÕ΢·þÎñÈí¼þ²âÊÔ
ÈçºÎ½øÐвâÊÔÐèÇó·ÖÎö£º´Ó½ÓÊÕÐèÇóµ½ÓÃÀýÉè¼Æ
python_selenium×Ô¶¯»¯²âÊÔ¿ò¼Ü
×îпγÌ
²âÊÔÐèÇó·ÖÎöÓë²âÊÔÓÃÀýÉè¼Æ
ÐÔÄܲâÊÔ·½·¨Óë¼¼Êõ
×Ô¶¯»¯²âÊÔ¿ò¼ÜÉè¼Æ¸ß¼¶Êµ¼ù
½Ó¿Ú×Ô¶¯»¯²âÊÔ·½·¨Ó빤¾ß
Èí¼þ²âÊÔ·½·¨Óëʵ¼ù(¹á´©°¸Àý)
³É¹¦°¸Àý
ij֧¸¶ÆóÒµ µ¥Ôª²âÊÔÓëÖØ¹¹Åàѵ
±±¾© Óû§ÌåÑé¡¢¿ÉÓÃÐÔ²âÊÔÓëÆÀ¹À
ij¾ü¹¤Ñо¿µ¥Î» ×Ô¶¯»¯²âÊÔ·½·¨¡¢°¸ÀýÓ빤¾ß
ÖªÃûÏû·Ñ½ðÈÚ¹«Ë¾ ̽Ë÷ÐÔ²âÊÔÓë²âÊÔ·ÖÎö
±±¾© º½Ìì¿Æ¹¤Ä³×Ó¹«Ë¾ Èí¼þ²âÊԼܹ¹Ê¦