????????????8?????????????ζ??????????FirstName??????????????????????????????????????????????????????б??????????????????????ζ???????????????????????????????????????????????????ChangeAssert?????????HasErrors?????

????[TestMethod]

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”????“Bob”????????????????????????????????LastName???null??????????????????????????????????嵥??

????1????FirstName??????“Adam”

????2????FirstName??????null

????3????FirstName ??????

????4????LastName??null??????£????case1-3

????5????LastName ??????????£????case1-3

????6????FirstName???null?????????£????case1-5

????7????FirstName??????????????£????case1-5

???????????????27?????????????????????????8???????????????????????????????????????216????????????????·???????????????δ???????????????????

??????????д???ζ??

??????????????????????8??????????????????????ú???????????????д??????????????????????????ζ???????????????????????е??????????????????ζ????

?????? Duplicated code

?????? ????????

?????? Excessively long identifiers

?????? ??????????

????????????????????????????????????????????????????ζ????

[TestMethod]
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");
}


????????????2?????????????????????????????????????????

???????????????????

?????????27?????????????????????????FirstName?null???????????????????????????????????????

[TestMethod]
public void Person_FirstName_Set_Empty()
{
     Person_FirstName_Set_Invalid(String.Empty);
}
[TestMethod]
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??????С???????????????????????

????[TestMethod]

public void Person_FirstName_Set_Valid()
{
     Person_FirstName_Set("Bob"?? false);
}
[TestMethod]
public void Person_FirstName_Set_Empty()
{
     Person_FirstName_Set(String.Empty?? true);
}
[TestMethod]
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");
     }
}