ÿ¸öÓÃÀý±àдһµ½¶þ¸ö¶ÏÑÔÊǵ¥Ôª²âÊÔ×î¼Ñʵ¼ùµÄ³£¼ûÄÚÈÝ¡£ÄÇÈç´ËÈÏΪµÄÊǼ«ÉÙºÍֻչʾһ¸öµ¥Ôª²âÊÔµÄÈË¡£Òò´ËÈç¹ûÄã²ÉÄÉËûÃǵĽ¨Ò飬Ϊһ¸öºÜСµÄÔËËãÄã¶¼ÐèÒª´óÁ¿µÄµ¥Ôª²âÊÔÈ¥±£Ö¤ÖÊÁ¿¡£ÕâÆªÎÄÕÂÒâͼͨ¹ýÀý×Óչʾ£¬Ò»¸ö²âÊÔÓÃÀý¶à¸ö¶ÏÑÔÊÇÓбØÒªºÍÓмÛÖµµÄ¡£
PersonÕâ¸ö¶ÔÏóÔÚÊý¾Ý°ó¶¨³¡¾°Öо³£³öÏÖ£¬ÎÒÃÇÀ´¿´Ï¡£

²âÊÔFirstName
µÚÒ»¸öÀ´²âÊÔFirstNameÕâ¸öÊôÐÔµÄÉèÖ㬿ªÊ¼ÈçÏ£º
public void Person_FirstName_Set() { varperson = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.AreEqual("Bob", person.FirstName); } |
½ÓÏÂÀ´ÎÒÃÇÀ´²âÊÔFirstNameµÄ¸Ä±ä֪ͨ¡£
public void Person_FirstName_Set_PropertyChanged() { var person = new Person("Adam", "Smith"); var eventAssert = new Granite.Testing.PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.Expect("FirstName"); } |
µ±ÎÒÃÇÖ´ÐÐÕâ¸ö²âÊÔʱ£¬»áµÃµ½Ò»¸öʧ°ÜÌáʾÐÅÏ¢¡°ÆÚÍûµÄÊôÐÔÃû¡®FirstName¡¯£¬µ«½ÓÊÕµ½µÄÊÇ¡¯IsChanged¡¯¡±¡£ÏÔÈ»£¬ÉèÖÃFirstNameµÄÊôÐÔ´¥·¢ÁË¡°IsChanged¡±±ê¼Ç£¬ÎÒÃÇÐèÒª°ÑËü¿¼ÂÇÔÚÄÚ¡£Òò´ËÎÒÃǰÑËü¼ÓÈ룺
public void Person_FirstName_Set_PropertyChanged() { var person = new Person("Adam", "Smith"); var eventAssert = new Granite.Testing.PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.SkipEvent(); //this was IsChanged eventAssert.Expect("FirstName"); } |
¼øÓÚÒÔÉÏÁ½¸ö²âÊÔ£¬ÎÒÃÇ¿¼Âǵ±FirstName±»ÐÞ¸Äʱ»¹ÓÐÆäËûʲôÊôÐÔ»á¸Ä±ä¡£²é¿´API£¬IsChangedºÍFullNameÊôÐÔ»á±ä»¯¡£
public void Person_FullName_Changed_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.AreEqual("Bob Smith", person.FullName); } |
public void Person_IsChanged_Changed_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.IsTrue(person.IsChanged); } |
µ±È»£¬Èç¹ûÕâЩÊôÐԸıäÁË£¬ÎÒÃÇÐèÒª»ñÈ¡µ½ÊôÐԸıä֪ͨ£º
public void Person_IsChanged_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.Expect("IsChanged"); } |
public void Person_FullName_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.SkipEvent(); //this was IsChanged eventAssert.SkipEvent(); //this was FirstName eventAssert.Expect("FullName"); } |
½ÓÏÂÀ´Á½¸ö²âÊÔÕë¶ÔHasErrorsÕâ¸öÊôÐÔºÍErrorsChangedʼþ¡£
public void Person_FirstName_Set_HasErrorsIsFalse() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.IsFalse(person.HasErrors); } |
public void Person_FirstName_Set_ErrorsChanged_Did_Not_Fire() { var person = new Person("Adam", "Smith"); var errorsChangedAssert = new ErrorsChangedEventAssert(person); person.FirstName = "Bob"; errorsChangedAssert.ExpectNothing(); } |
ĿǰÎÒÃÇÓÐ8¸ö²âÊÔÁË£¬ÕâÒâζ×ŵ±ÎÒÃÇÐÞ¸ÄFirstNameµÄÊôÐÔÖµ£¬ÎÒÃÇÒª¿¼ÂǻᷢÉú¸Ä±äµÄÿ¼þÊ¡£µ«ÊÇÕâ²»ËãÍê¡£ÎÒÃÇ»¹ÐèҪȷ±£Ã»ÓбðµÄ»á±»ÒâÍâ¸Ä±ä¡£ÀíÂÛÉÏ˵£¬ÕâÒâζןü¶àµÄ¶ÏÑÔºÍÏ൱ÊýÁ¿µÄ²âÊÔ£¬µ«ÊÇ£¬½ÓÏÂÀ´ÎÒÃDzÉÓÃÈ¡Çɵķ½·¨£¬ÓÃChangeAssert·½·¨À´Ìæ´úHasErrors²âÊÔ¡£
public void Person_FirstName_Set_Nothing_Unexpected_Changed() { var person = new Person("Adam", "Smith"); var changeAssert = new ChangeAssert(person); person.FirstName = "Bob"; changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged"); } |
ChangeAssert¼òµ¥µØÍ¨¹ýÓ³Éä»ñÈ¡¶ÔÏóµÄ״̬£¬Òò´Ë£¬ÉÔºóÄã¿ÉÒÔ¶ÏÑÔµ½³ýÁËÄãÖ¸³öµÄ¼¸¸ö¾ßÌåÊôÐÔÆäËûµÄû±ä¡£
¹§Ï²£¬ÄãÍê³ÉÁËÄãµÄµÚÒ»¸ö²âÊÔÓÃÀý¡£Íê³ÉÒ»¸ö£¬»¹ÓкܶàºÜ¶àµÈ×Å¡£
Ϊʲô˵ÊÇ¡°Ò»¸ö¡±²âÊÔÓÃÀý£¿
ÄÇ8¸ö²âÊÔÖ»ÊÇÍê³ÉÁ˸²¸ÇFirstNameÊôÐÔ´Ó¡°Adam¡±Ð޸ijɡ°Bob¡±ÕâÒ»¸ö³¡¾°£¬ÔÚÆäËûµÄֵûÓÐÔÚ´íÎó״̬¡¢LastName²»Îªnull»ò¿ÕµÄÇé¿öÏ¡£ÈÃÎÒÃÇ¿´¿´²âÊÔÓÃÀýµÄÍêÕûÇåµ¥£º
½«FirstNameÖµÉèÖÃΪ¡°Adam¡±
½«FirstNameÖµÉèÖÃΪnull
½«FirstName ÉèΪ¿Õ´®
ÔÚLastNameֵΪnullµÄÇé¿öÏ£¬Ö´ÐÐcase1-3
ÔÚLastName Ϊ¿Õ´®µÄÇé¿öÏ£¬Ö´ÐÐcase1-3
ÔÚFirstNameÖµÒÔnull¿ªÍ·µÄÇé¿öÏ£¬Ö´ÐÐcase1-5
ÔÚFirstNameÖµÒÔ¿Õ´®¿ªÍ·µÄÇé¿öÏ£¬Ö´ÐÐcase1-5
ĿǰÎÒÃÇ¿´µ½ÁË27¸ö²»Í¬µÄ³¡¾°¡£Èç¹ûÿ¸ö³¡¾°ÐèÒª8¸ö²»Í¬²âÊÔ£¬½ö½öΪÕâÒ»¸öÊôÐÔ£¬ÎÒÃÇÐèÒªÖ´ÐÐÖÁ¶à216¸ö²âÊÔ¡£¸ù¾ÝÕâÖÖ˼·£¬ÕâÊÇÏ൱ËöËéµÄÒ»¶Î´úÂë¡£Òò´ËÎÒÃǸÃÔõô×öÄØ£¿
²âÊÔÒ²ÓдúÂëζµÀ
»Ø¿´µÚÒ»¸ö²âÊÔÓÃÀýµÄ8¸ö²âÊÔ£¬ËüÃǶ¼ÓÐͬÑùµÄÉèÖúÍÔËË㡣ΨһµÄ²»Í¬ÊÇÎÒÃÇдµÄ¶ÏÑÔ¡£ÔÚÒµ½çÕâ¸ö±»³ÆÎªÒ»¸ö´úÂëζµÀ¡£ÊÂʵÉÏ£¬¸ù¾Ýά»ù°Ù¿ÆËùÁеÄÕâÀïÓ¦¸ÃÓÐÁ½¸ö´úÂëζµÀ£º
1.Duplicated code
2.ÖØ¸´µÄ´úÂë
3.Excessively long identifiers
4.¹ý³¤µÄ±êʶ·û
ÎÒÃÇ¿ÉÒÔͨ¹ý½«¶ÏÑԺϲ¢µ½Ò»¸ö²âÊÔÀ´ÇáËɵØÏû³ýÕâÁ½¸ö´úÂëζµÀ£º
public void Person_FirstName_Set() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); var errorsChangedAssert = new ErrorsChangedEventAssert(person); var changeAssert = new ChangeAssert(person); person.FirstName = "Bob"; Assert.AreEqual("Bob", person.FirstName, "FirstName setter failed"); Assert.AreEqual("Bob Smith", person.FullName, "FullName not updated with FirstName changed"); Assert.IsTrue(person.IsChanged, "IsChanged flag was not set when FirstName changed"); eventAssert.Expect("IsChanged"); eventAssert.Expect("FirstName"); eventAssert.Expect("FullName"); errorsChangedAssert.ExpectNothing("Expected no ErrorsChanged events"); changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged"); } |
ÖªµÀʲôµ¼Ö²âÊÔʧ°ÜºÜÖØÒª£¬Òò´ËÎÒÃÇÔÚ¶ÏÑÔÀïÌí¼Óʧ°ÜµÄÐÅÏ¢Ìáʾ¡£
µ¥Ôª²âÊԺʹúÂëÖØÓÃ
»Ø¿´ÄÇ27¸ö²âÊÔÓÃÀý£¬ÎÒÃÇ¿ÉÒԶ϶¨ÉèÖÃFirstNameΪnull»òÕ߿մ®Ó¦¸ÃÒ²ÐèÇóͬÑùµÄ²âÊÔ¡£Òò´ËÎÒÃÇ¿ÉÒÔÀ©Õ¹³É£º
public void Person_FirstName_Set_Empty() { Person_FirstName_Set_Invalid(String.Empty); } |
public void Person_FirstName_Set_Null() { Person_FirstName_Set_Invalid(null); } public void Person_FirstName_Set_Invalid(string firstName) { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); var errorsChangedAssert = new ErrorsChangedEventAssert(person); var changeAssert = new ChangeAssert(person); Assert.IsFalse(person.IsChanged, "Test setup failed, IsChanged is not false"); Assert.AreEqual("Adam", person.FirstName, "Test setup failed, FirstName is not Adam"); Assert.AreEqual("Smith", person.LastName, "Test setup failed, LastName is not Smith"); person.FirstName = firstName; Assert.AreEqual(firstName , person.FirstName, "FirstName setter failed"); Assert.AreEqual("Smith", person.FullName, "FullName not updated with FirstName changed"); Assert.IsTrue(person.IsChanged, "IsChanged flag was not set when FirstName changed"); eventAssert.Expect("IsChanged"); eventAssert.Expect("FirstName"); eventAssert.Expect("FullName"); Assert.IsTrue(person.HasErrors, "HasErrors should have remained false"); errorsChangedAssert.ExpectCountEquals(1, "Expected an ErrorsChanged event"); changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged", "HasErrors"); } |
¿ÉÒÔ·¢ÏÖPerson_FirstName_SetºÍPerson_FirstName_Set_InvalidµÄ²îÒìºÜС£¬ÎÒÃÇ¿ÉÒÔ½øÒ»²½ÊÔ×ÅͨÓû¯£º
public void Person_FirstName_Set_Valid() { Person_FirstName_Set("Bob", false); } |
public void Person_FirstName_Set_Empty() { Person_FirstName_Set(String.Empty, true); } |
public void Person_FirstName_Set_Null() { Person_FirstName_Set(null, true); } public void Person_FirstName_Set(string firstName, bool shouldHaveErrors) { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); var errorsChangedAssert = new ErrorsChangedEventAssert(person); var changeAssert = new ChangeAssert(person); Assert.IsFalse(person.IsChanged, "Test setup failed, IsChanged is not false"); Assert.AreEqual("Adam", person.FirstName, "Test setup failed, FirstName is not Adam"); Assert.AreEqual("Smith", person.LastName, "Test setup failed, LastName is not Smith"); person.FirstName = firstName; Assert.AreEqual(firstName, person.FirstName, "FirstName setter failed"); Assert.AreEqual((firstName + " Smith").Trim(), person.FullName, "FullName not updated with FirstName changed"); Assert.AreEqual(true, person.IsChanged, "IsChanged flag was not set when FirstName changed"); eventAssert.Expect("IsChanged"); eventAssert.Expect("FirstName"); eventAssert.Expect("FullName"); if (shouldHaveErrors) { Assert.IsTrue(person.HasErrors, "HasErrors should have remained false"); errorsChangedAssert.ExpectCountEquals(1, "Expected an ErrorsChanged event"); changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged", "HasErrors"); } else { errorsChangedAssert.ExpectNothing("Expected no ErrorsChanged events"); changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged"); } } |
ÔÚ²âÊÔ´úÂë±äµÃÁîÈËÃÔ»ó֮ǰ£¬ÎÒÃÇ¿ÉÒÔ°ÑËüͨÓû¯Ê²Ã´³Ì¶È£¬ÕâÀï¾ø¶ÔÓиöÏÞÖÆ¡£µ«ÊÇÒ»¸öÓÐÒâÒåµÄ²âÊÔÃû³Æ£¬²¢¸øÃ¿¸ö¶ÏÑÔÅäÒ»¸öºÃµÄÃèÊö¿ÉÒÔÈÃÄãµÄ²âÊÔ¸ü¼ÓÈÝÒ×ÈÃÈËÀí½â¡£
¿ØÖƱäÁ¿
ĿǰËùÓеĶÏÑÔ¶¼Ö»¿¼Âǵ½Á˲âÊÔÓÃÀýµÄÊä³ö¡£ËûÃǼÙÉèÿ¸öPerson¶ÔÏó³õʼ״̬ÒÑÖª£¬È»ºó´Ó´Ë³ö·¢½øÐÐÆäËû²Ù×÷¡£µ«ÊÇÈç¹ûÎÒÃÇÏëÈòâÊÔ¸ü¾ß¿ÆÑ§ÐÔ£¬±ØÐëÈ·±£ÎÒÃÇÄÜ¿ØÖƱäÁ¿¡£»òÕß»»¾ä»°Ëµ£¬ÎÒÃÇÐèÒª±£Ö¤£¬Ò»ÇÐÔÚÕÆÎÕÖ®ÖС£
Çë¿´ÏÂÃæÒ»×é¶ÏÑÔ£º
Assert.IsFalse(person.HasErrors, "Test setup failed, HasErrors is not false"); Assert.IsFalse(person.IsChanged, "Test setup failed, IsChanged is not false"); Assert.AreEqual("Adam", person.FirstName, "Test setup failed, FirstName is not Adam"); Assert.AreEqual("Smith", person.LastName, "Test setup failed, LastName is not Smith"); |
ÓÉÓÚÎÒÃDz»ÏëÔÚÿ¸ö²âÊԵĿªÊ¼Öظ´ÕâЩ¶ÏÑÔ£¬ÎÒÃÇ¿ÉÒÔÑ¡Ôñ°ÑËûÃÇÒÆµ½Ò»¸ö¹¤³§·½·¨ÖУ¬ÕâÑùÎÒÃÇ¿ÉÒÔ±£Ö¤×ÜÊÇÄõ½Ò»¸ö¸É¾»µÄ¶ÔÏó¡£Õâ¸öͬÑùÊÊÓÃÓÚÖØÓÃÕâЩÉèÖÃÈ¥²âÊÔÆäËûÊôÐԵIJâÊÔÓÃÀý¡£
public void Person_FirstName_Set() { var person = GetAdamSmith(); ... |
±í¸ñʽµÄ²âÊÔ
Ö®ËùÒÔ×ßµ½ÕâÒ»²½£¬ÊÇÒòΪ¡°²âÊÔ·½·¨¡±µÄÊýÁ¿¸ú²âÊÔµÄÍêÉÆ³Ì¶ÈûÓйØÏµ¡£ËüÃÇÖ»ÊÇ×éÖ¯ºÍÖ´ÐвâÊÔÓÃÀýÒ»ÖֱȽϷ½±ãµÄ·½Ê½¡£
ÁíÒ»¸ö×éÖ¯´óÁ¿²âÊÔÓÃÀýµÄ·½·¨ÊDZí¸ñÇý¶¯²âÊÔ·¨¡£²»ÄÜÖ´Ðе¥¸ö²âÊÔ£¬µ«ÊǽöÓÃÒ»ÐдúÂë¾Í¿ÉÒÔÔö¼ÓеIJâÊÔÓÃÀý¡£±í¸ñʽ²âÊÔÀïµÄ±í¸ñ¿ÉÒÔÀ´Ô´ÓÚXMLµÄÎļþ£¬Êý¾Ý¿â±í£¬Ð´ËÀÔÚÊý×éÀï»òÕßÖ»ÊÇʹÓÃͬһ¸öº¯ÊýÓò»Í¬µÄÖµ·´¸´µ÷Óá£Ò»Ð©¿ò¼ÜÈçMBTestÉõÖÁ¿ÉÒÔÈÃÄãÓÃÊôÐÔ¸ø³ö²âÊÔÓÃÀý£¬µ«ÊÇΪÁËÈÃÀý×ÓÇá±ã£¬ÎÒÃÇ»¹ÊǼá³Ö±£³Ö×îµÍµÄ¹²Í¬²¿·Ö¡£
public void Person_FullName_Tests() { Person_FullName_Test("Bob", "Jones", "Bob Jones"); Person_FullName_Test("Bob ", "Jones", "Bob Jones"); Person_FullName_Test(" Bob", "Jones", "Bob Jones"); Person_FullName_Test("Bob", " Jones", "Bob Jones"); Person_FullName_Test("Bob", "Jones ", "Bob Jones"); Person_FullName_Test(null, "Jones", "Jones"); Person_FullName_Test(string.Empty, "Jones", "Jones"); Person_FullName_Test(" ", "Jones", "Jones"); Person_FullName_Test("Bob", "", "Bob"); Person_FullName_Test("Bob", null, "Bob"); Person_FullName_Test("Bob", string.Empty, "Bob"); Person_FullName_Test("Bob", " ", "Bob"); } private void Person_FullName_Test(string firstName, string lastName, string expectedFullName) { var person = GetAdamSmith(); person.FirstName = firstName; person.LastName = lastName; Assert.AreEqual(expectedFullName, person.FullName, string.Format("Incorrect full name when first name is '{0}' and last name is '{1}'" firstName ?? "", lastName ?? "")); } |
ÔÚÔËÓÃÕâ¸ö¼¼ÇÉʱ£¬ÒªÊ¹Óôø²ÎÊýµÄ´íÎóÐÅÏ¢£¬ÕâºÜÖØÒª¡£Èç¹û²»¼Ó£¬Äã»á·¢ÏÖÔÚ¶¨Î»ÄÄЩ²ÎÊý×éºÏ²»¶Ôʱ£¬»¹µÃÒ»²½Ò»²½µ÷ÊÔ´úÂë¡£
½áÂÛ
ÔÚΪÈκαäÁ¿±àдµ¥Ôª²âÊÔʱ£¬×îºÃ³¢ÊÔ×î´ó»¯ÒÔϼ¸¸öÒòËØ£º
1.ÓÐÒâÒåµÄµ¥Î»¹¤×÷Á¿²âÊÔ¸²¸ÇÂÊ
2.Ãæ¶Ô±ä¶¯µÄ´úÂë»ùÏßʱ£¬±£Ö¤¿Éά»¤ÐÔ
3.²âÊÔÌ×¼þµÄÐÔÄÜ
4.Ã÷ȷ˵Ã÷²âÊÔʲôÒÔ¼°ÎªÊ²Ã´
¼øÓÚÕâЩÒòËØÍùÍù»á³åÍ»£¬½÷É÷µØÔËÓõ¥¸öÓÃÀý¶àÖØ¶ÏÑÔ¿ÉÌáÉýÉÏÊöËĸö·½Ã棬¾ßÌå×ö·¨ÊÇ£º + ¼õÉÙÐèÒª±àдµÄÑù°å´úÂëÁ¿
+ ¼õÉÙÒòAPI¸ü¸Ä¶øÐèÒª¸üеÄÑù°å´úÂëÁ¿ + ¼õÉÙÿ¸ö¶ÏÑÔÐèÒªÖ´ÐеÄÑù°å´úÂëÊýÁ¿ + ½«Ä³Ò»²Ù×÷µÄËùÓжÏÑÔ£¬ÓÃÎĵµ¼Ç¼ÔÚͬһ¸öµØ·½¡£
|