CSharp-4.0 - 新测试会导致旧测试中断,我是否这么做?

  显示原文与译文双语对照的内容
0 0

我有一个单元测试,测试一个宝宝的名字是否没有提供,另一个名称是否保存。 我做了 red/green/refactor 并且它通过了。 我添加了新的测试,这些测试对姓氏。 因为没有提供姓,所以名字的测试是失败的。 我已经在下面提供了测试代码。 我想知道是否正确的方法,或者我只是希望能够正确地修改这些测试。

除了使用软件,否则我将把这些检查编码到宝宝类本身。

我现在已经收到了几个月的更新:根据我已经收到的回复,我想应该是错误的。 我应该做什么,这样才不会出现这种情况?


 [TestMethod]
 public void baby_is_not_saved_if_validation_fails() {
//arange
 var validator = new Mock<IValidator<Baby>>();
 var output = new ValidationCollection();
 validator.Setup(v => v.IsValid(It.IsAny<Baby>(), out output)).Returns(false);
 var unitOfWork = GetMock();
//act
 var b = new Baby();
 var svc = new BabyService(validator.Object, unitOfWork.Object);
 svc.AddNewBaby(b);
//assert
 unitOfWork.Verify(u => u.SaveChanges(), Times.Never());
 }

 [TestMethod]
 public void baby_is_saved_if_validation_passes() {
//arange
 var validator = new Mock<IValidator<Baby>>();
 var output = new ValidationCollection();
 validator.Setup(v => v.IsValid(It.IsAny<Baby>(), out output)).Returns(true);
 var unitOfWork = GetMock();
//act
 var b = new Baby();
 var svc = new BabyService(validator.Object, unitOfWork.Object);
 svc.AddNewBaby(b);
//assert
 unitOfWork.Verify(u => u.SaveChanges(), Times.Once());
 }

 [TestMethod]
 public void if_first_name_is_not_supplied_baby_is_not_added() {
//arrange
 var validator = new DefaultBabyValidator();
 var unitOfWork = GetMock();
//act
 var b = new Baby();
 var svc = new BabyService(validator, unitOfWork.Object);
 svc.AddNewBaby(b);
//assert
 unitOfWork.Verify(u => u.SaveChanges(), Times.Never());
 }

 Mock<IHealthUnitOfWork> GetMock() {
 var uow = new Mock<IHealthUnitOfWork>();
 var dbSet = new Mock<IDbSet<Baby>>();
 dbSet.Setup(db => db.Add(It.IsAny<Baby>())).Returns(new Baby());
 uow.Setup(u => u.SaveChanges()).Verifiable();
 uow.SetupGet(u => u.Babies).Returns(dbSet.Object);

 return uow;
 }

 [TestMethod]
 public void if_first_name_is_supplied_baby_is_added() {
//arrange
 var validator = new DefaultBabyValidator();
 var unitOfWork = GetMock();
//act
 var b = new Baby { FirstName ="Charles" };
 var svc = new BabyService(validator, unitOfWork.Object);
 svc.AddNewBaby(b);
//assert
 unitOfWork.Verify(u => u.SaveChanges(), Times.Once());
 }

 [TestMethod]
 public void if_last_name_is_not_supplied_baby_is_not_added() {
//arrange
 var validator = new DefaultBabyValidator();
 var unitOfWork = GetMock();
//act
 var b = new Baby { FirstName ="Charles" };
 var svc = new BabyService(validator, unitOfWork.Object);
 svc.AddNewBaby(b);
//assert
 unitOfWork.Verify(u => u.SaveChanges(), Times.Never());
 }
}

时间: 原作者:

0 0

你的问题是你的测试代表了矛盾的要求。 如果提供了第一个名字并且最后一个名字不存在,那么 if_first_name_is_supplied_baby_is_added() 说该宝宝应该保存。

原作者:
0 0

问题是,第一个名字的初始测试没有最后一个名字的规格。 当你的规格改变之后,你的测试会改变。 我已经重构了测试,所以我不需要改变以前的测试,因为在婴儿类中发现新的字段。 我现在有一个检验有效婴儿 true 条件的测试方法。 所需的字段测试现在检查以下内容:

  • 如果必填字段无效
    • IsValid必须 return false
    • 返回的集合中必须存在预期的异常( AggregateException 。InnerExceptions )
  • 如果必填字段有效
    • 只检查预期的异常是否存在

现在我只需要在发现新字段时更新一个测试( 所有字段都是有效的测试) 。


[TestMethod]//only update this one as new fields are discovered
public void when_baby_is_valid_validation_returns_true() {
 var validator = new DefaultBabyValidator();

//valid baby goes here
 var baby = new Baby();

 AggregateException fail;
 Assert.IsTrue(validator.IsValid(baby, out fail));
}

[TestMethod]
public void validation_returns_exception_if_first_name_is_null() {
 var validator = new DefaultBabyValidator();
 AggregateException results;
 var isValid = validator.IsValid(new Baby(), out results);
 var expected = results.InnerExceptions
. OfType<ArgumentException>()
. SingleOrDefault(ex => ex.ParamName =="FirstName");
 Assert.IsFalse(isValid);//should always return false if this condition is met
 Assert.IsNotNull(expected);//should also contain the expected exception
}

[TestMethod]
public void validation_does_not_return_exception_if_first_name_is_valid() {
 var validator = new DefaultBabyValidator();
 AggregateException results;
 validator.IsValid(new Baby { FirstName ="Charles" }, out results);
 var expected = results.InnerExceptions
. OfType<ArgumentException>()
. SingleOrDefault(ex => ex.ParamName =="FirstName");
 Assert.IsNull(expected);//exception should not exsist. 
//We don't care if it returns true.
//There is only one case where IsValid should
//return true.
}

原作者:
...