现在,当我运行单元测试,它表示通过。

  它确认行为PageRepository没有改变,尽管它的代码急剧变化。有了正确的单元测试,即使你在代码中改变了,只要你的单元测试全部通过,你的系统是没有问题。接下来让我们来测试,当缓存满了,它正确地从缓存中返回一个对象,而不是不必要的查询数据库。下面的试验将确保:
  [Specification]
  public void GetPage_Should_Return_A_Page_from_cache_when_it_is_already_cached()
  {
  var cache = new Mock();
  var database = new Mock();
  IPageRepository pageRepository = new PageRepository(database.Object, cache.Object);
  const int pageId = 1;
  var page = default(Page);
  var samplePage = new Page() { ID = pageId, Title = "Test Page",
  ColumnCount = 3, LayoutType = 3, UserId = Guid.Empty, VersionNo = 1,
  PageType = Enumerations.PageTypeEnum.PersonalPage,
  CreatedDate = DateTime.Now };
  "Given PageRepository and the requested page in cache".Context(() =>
  {
  cache.Expect(c => c.Get(CacheSetup.CacheKeys.PageId(samplePage.ID)))
  .Returns(samplePage);
  });
  "when GetPageById is called".Do(() =>
  page = pageRepository.GetPageById(1));           
  "it checks in the cache first and finds the object is in cache".Assert(() =>
  {
  cache.VerifyAll();
  });
  "it returns the page as expected".Assert(() =>
  {
  Assert.Equal(pageId, page.ID);
  });
  }
  这个试验是很简单的。的区别是在设置Context ,我们设定一个期望,从缓存请求特定的页面时,它将返回samplePage对象。只要其中任何被调用函数中有没有期望设置,Mock将抛出一个异常。如果代码试图调用任何database对象或任何东西上的其他cache对象时,它会抛出一个异常,从而表明它没有做什么不应该做的。
  集成测试使用BDD
  集成测试意味着你要测试的一些类,它与其它类和基础设施集成,如数据库,文件系统,邮件服务器等,当你写一个集成测试,测试组件的行为应该是没有任何实物模型。此外,它们提供额外的信心代码工作,因为所有必需的组件和依赖关系也被测试。
  如何测试业务外观层,业务外观处理数据访问组件和所有其他实用程序组件的编排。它封装了用户操作为一体的商业运作。例如,在Dropthings ,当第一次全新的用户访问,用户获得创建默认的页面和窗口小部件。这些页面和小部件来自一个模板。有一个名为anon_user@dropthings.com的用户拥有默认的页面和窗口小部件。特定用户的页面和窗口小部件被复制到每一个新用户中。由于这是一个复杂的操作,适合做自动化的集成测试。
  当用户首次访问该Default.aspx,该FirstVisitHomePage是呼吁Facade。它通过一个复杂的过程来克隆模板页面、小部件和设置默认用户设置等集成测试,将确保如果FirstVisitHomePage被调用参数标识一个新的用户访问的站点,那么它将返回可以对用户创建的默认页面和部件的一个对象。因此: 由于之前从来没有谁访问过该网站的匿名用户, 当用户第一次访问, 然后在准确的列和位置作为anon_user的网页新创建的页面创建的小部件。
  public class TestUserVisit
  {
  public TestUserVisit()
  {
  Facade.BootStrap();
  }
  ///
  /// Ensure the first visit produces the pages and widgets defined in the template user
  ///
  [Specification] public void First_visit_should_create_same_pages_and_widgets_as_the_template_user() { MembershipHelper.UsingNewAnonUser((profile) => { using (var facade = new Facade(new AppContext(string.Empty, profile.UserName))) { UserSetup userVisitModel = null; // Load the anonymous user pages and widgets string anonUserName = facade.GetUserSettingTemplate() .AnonUserSettingTemplate.UserName; var anonPages = facade.GetPagesOfUser(facade.GetUserGuidFromUserName(anonUserName)); "Given anonymous user who has never visited the site before" .Context(() => { }); "when the user visits for the first time".Do(() => { userVisitModel = facade.FirstVisitHomePage(profile.UserName, string.Empty, true, false); }); "it creates widgets on the newly created page at exact columns and positions as the anon user's pages".Assert(() => { anonPages.Each(anonPage => { var userPage = userVisitModel.UserPages.First(page => page.Title == anonPage.Title && page.OrderNo == anonPage.OrderNo && page.PageType == anonPage.PageType); facade.GetColumnsInPage(anonPage.ID).Each(anonColumn => { var userColumns = facade.GetColumnsInPage(userPage.ID); var userColumn = userColumns.First(column => column.ColumnNo == anonColumn.ColumnNo); var anonColumnWidgets = facade.GetWidgetInstancesInZoneWithWidget(anonColumn.WidgetZoneId); var userColumnWidgets = facade.GetWidgetInstancesInZoneWithWidget(userColumn.WidgetZoneId); // Ensure the widgets from the anonymous user template's columns are // in the same column and row. anonColumnWidgets.Each(anonWidget => Assert.True(userColumnWidgets.Where(userWidget => userWidget.Title == anonWidget.Title && userWidget.Expanded == anonWidget.Expanded && userWidget.State == anonWidget.State && userWidget.Resized == anonWidget.Resized && userWidget.Height == anonWidget.Height && userWidget.OrderNo == anonWidget.OrderNo).Count() == 1)); }); }); }); } }); }
  需要进一步的解释:为从模板用户发现每个页面确保新用户从模板用户的页面的部件获得完全一样的页面。获得来自新用户的页面的窗口小部件比较每个插件。当在做业务层的变化对于每个插件确保具有相同的名称,状态,位置等的部件,我可以运行集成测试,以确保关键功能是否按预期工作完成,而且在整个业务层没有破损任何地方。 我用xunit.console.exe上运行的集成测试测试并生成一个不错html报告:

  该报告使用下面的命令行产生: d:xunitxunit.console.exe d: runksrcDropthings.Business.Facade.TestsinDebugDropthings.Business.Facade.Tests.dll /html FacadeTest.html
  您可以使用GUI xUnit: