需要再次保证单元测试和最佳实践

时间:2010-11-14 07:23:14

标签: unit-testing moq

我现在7个月没有进行过TDD和单元测试了,我有点忘了。我现在在商店里想要开始这样做,但我是那里唯一的一个 并不完全是这个问题的大师。

我有点生疏,我得到各种各样的问题,很多次我都无法给出正确答案。

我得到的典型问题:

  • 我没有看到任何问题 集成测试?我告诉他们的是 慢,你永远不应该这样做。

    如果我 无法测试privateMethod(我知道 MSTest确实)有什么意义 测试?我所有重要的方法都是 私有的。

    我没有看到设置的重点 期望并返回一个结果 请考试?

    您的典型单元测试是什么? 应该在每一层执行?应该 你只在边界水平测试?

    如何 测试我的存储过程返回 预期的结果?

你认为以下测试对你有意义吗?你通常会在每一层进行什么样的测试?有代码的例子吗?

我做了3种测试

1)ViewModel测试。

2)Wcf通过模拟服务进行测试

3)Wcf Integratontest但嘲笑Dal

这是你做的吗?。如果你错了,可以纠正我。你可以改进吗?

ViewModel测试   财产已经改变   和方法被称为下面的例子

      //property has changed
      [TestMethod]
      public void Should_be_able_to_test_that_customer_description_propertyChanged_was_raised()
      {
         //act
         var customerResponse=new CustomerResponse{Description = "Test"};
         var customerViewModel = new CustomerViewModel(customerResponse);
         var eventWasRaised = false;

         customerViewModel.PropertyChanged += (sender, e) => eventWasRaised = e.PropertyName == "Description";
         customerViewModel.Description = "DescriptionTest";


         Assert.IsTrue(eventWasRaised, "PropertyChanged event was not raised correctly.");
      }

        //Testing a method on the view model has been called
        [Test]
        public void Should_be_able_to_test_that_insert_method_on_view_Model_has_been_executed()
        {
            var mock = new Mock<IRepository>();
            var employeeVm = new EmployeeVM(mock.Object) {Age = 19};
            employeeVm.SaveCommand.Execute(null);
            mock.Verify(e=>e.Insert(It.IsAny<Employee>()));
        }

WCF单元测试

//测试1模拟服务

      [TestMethod]
      public void Should_be_able_to_verify_getCustomer_has_been_called)
      {
         var mockService = new Mock<ICustomer>();
         var expectedCustomer=new Customer{Id=1,Name="Jo"};
         mockService.Setup(x => x.GetCustomer(It.IsAny<int>())).Returns(expectedCustomer);

         var customerViewModel = new customerViewModel(mockService.Object);
         customerViewModel.GetCustomer.Execute(null);

         mockService.Verify(x=>x.GetCustomer(),Times.AtLeastOnce());
      }

      //Test 2 mocking the repository
      [TestMethod]
      public void Should_be_able_to_verify_getCustomer_has_been_called_on_the_service)
      {
         var mockRepository = new Mock<IRepositoryCustomer>();
         var expectedCustomer=new Customer{Id=1,Name="Jo"};
         mockRepository.Setup(x => x.GetCustomer(It.IsAny<int>())).Returns(expectedCustomer);

         var customerService = new CustomerService(mock.Object);
         customerService.GetCustomer(1);

         mockRepository.Verify(x=>x.GetCustomer(),Times.AtLeastOnce());
      }

2 个答案:

答案 0 :(得分:3)

好的,让我们看看我是否可以回答

I dont see anything wrong with integration Testing? I told them is
     

慢,你永远不应该这样做。

集成测试现在是一个重载的术语。 当您编写单元测试时,您希望将假冒/模拟替换为耗时/不可预测/昂贵的真实合作者,以便您可以专注于您自己的代码(并假设真实的合作满足假定的合同)。这可以帮助您在很短的时间内运行单元测试,从而加快反馈和进度。此外,测试失败现在表示代码中存在错误。相反,任何依赖项中的任何错误都可能导致测试失败

您还需要其他(慢速)测试来验证真实的拼贴(例如DAL)是否按照合同行事。 (我倾向于现在称这些集成测试)

  

如果我无法测试privateMethod(我知道MSTest会这样做)有什么意义呢   测试?我所有重要的方法都是   私有的。

私有方法应该通过运行它们的公共接口进行测试。为调用私有方法的公共方法编写测试。如果无法做到这一点,私有方法或部分方法可能是多余的。

  

我没有看到设置的重点   期望并返回一个结果   请考试?

请参阅答案#1-您假设真正的依赖关系将按照约定的合同行事。这使您可以专注于使用依赖项编写的代码。

  

您的典型单元测试是什么?   应该在每一层执行?应该   你只在边界水平测试?

单元测试应测试对象,验收测试验证所有对象在插入彼此时协同工作

  

如何测试我的存储过程返回预期结果?

编写一个测试,针对已知参考数据库运行DAL并验证预期结果。这应该被标记为慢速集成测试(根据我选择的定义)。

答案 1 :(得分:1)

你写的测试是一个非常好的开始!尝试一下,练习和研究哪些有效,哪些无效,那么任何一个“大师”的人如何成为一个人。 (我还没有见过任何'大师';只是有多年练习的人。)

有几个问题,所以我将轮流回答。

集成测试非常慢,是的。

对于整个系统中的某些关键方案,我通常会在Gui或网页上为整个应用程序执行此操作,因为手动执行相同的测试非常耗时。随着应用程序的增长,测试人员必须进行的回归测试量也会增加。您可以通过编写这些自动化测试来帮助他们。

开发人员几乎没有看到自动化测试的好处,因为测试人员确实需要他们并使用它们。从他们的角度考虑它,你可能会看到更多的价值。

实际上,首先导出场景可能很有价值,因为它可以帮助开发人员,测试人员和分析人员找到并解决他们对系统的理解上的差异。

测试私有方法应该是不必要的。然而...

如果您的方法很复杂,您可以随时将其拆分为不同的类,并使您的类与该类协作。如果您的私人方法很重要,那么您可能应该这样做。

另外,不要测试方法。描述你班级行为的每个方面,说明它有价值的原因,并给出一些使用它的例子。行为可能涉及多种方法。例如,list.isEmpty要求我们也与list.add合作;这是他们之间的互动,这对使用list的事物非常重要。

这也是我们不测试私有方法的原因 - 因为它们对使用它们的类没有任何好处。

您的测试名称可能有助于反映这一点。想想“我的观点模型应该......”,然后考虑它如何提供它所做的有价值的行为。例如,我会将您的第一个测试称为“我的视图模型应该通知侦听器描述已更改”,因此ShouldNotifyListenersThatTheDescriptionChanged

不要设置期望,而应考虑您的班级有一些合作课程。

其中一些为类提供信息 - 改变其行为的上下文,产生不同的结果。他们中的一些人为班级做了工作。第一个是“存根”,第二个是“模拟”(这里的术语与业务混合在一起)。

不是设定期望,而是提供一个示例,说明该类在该上下文中的行为。

而不是验证结果,而是表明该类正确地委派了它的职责。

模拟只是一种有用的方法。

我编写的典型测试是帮助我描述代码行为,确保其职责适当并说明代码有价值的原因。这是大多数代码,但我不会为普通类编写示例 - 例如,自定义异常,只是数据或属性的对象等。

您可以通过编写在不同上下文中使用它的示例来显示存储过程的行为,这些上下文显示了行为的不同方面。您可能需要设置一些数据才能生效。我工作的大多数团队都是因为测试难度而避免存储过程,或者只是依靠全栈场景来提供覆盖。

希望这有帮助,祝你好运!