单元测试和集成测试业务应用程序(2)

发表于:2016-06-01来源:不详作者:Omar Al Zabir点击数: 标签:单元测试
public void GetPage_Should_Return_A_Page_from_database_when_cache_is_empty_and_then_caches_it() { var cache = new Mock(); var database = new Mock(); IPageRepository pageRepository = new PageRepository

  public void GetPage_Should_Return_A_Page_from_database_when_cache_is_empty_and_then_caches_it()

  {

  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", ...};

  database

  .Expect(d => d.GetSingle(

  DropthingsDataContext.SubsystemEnum.Page,

  1, LinqQueries.CompiledQuery_GetPageById))

  .Returns(samplePage);

  "Given PageRepository and empty cache".Context(() =>

  {

  // cache is empty

  cache.Expect(c => c.Get(It.IsAny())).Returns(default(object));

  // It will cache the Page object afte loading from database

  cache.Expect(c =>

  c.Add(It.Is(cacheKey =>

  cacheKey == CacheSetup.CacheKeys.PageId(pageId)),

  It.Is(cachePage =>

  object.ReferenceEquals(cachePage, samplePage))))

  .AtMostOnce().Verifiable();

  });

  "when GetPageById is called".Do(() =>

  page = pageRepository.GetPageById(1));

  "it checks in the cache first and finds nothing and then caches it".Assert(() =>

  cache.VerifyAll());

  "it loads the page from database".Assert(() =>

  database.VerifyAll());

  "it returns the page as expected".Assert(() =>

  {

  Assert.Equal(pageId, page.ID);

  });

  }

  单元测试的意义何在?

  我觉得写单元测试时,所测试的方法不只是在调用测试方法。单元测试已经确切地知道什么其它的类和方法将被调用。在上面的例子中,是否使用cache或database是在方法中决定的,所以,可以进行逻辑测试。例如,我改变了代码来使用AspectF库。这需要代码变更PageRepository 。更改代码后,我需要确保PageRepository还是按照预期的行为。不管我用什么方法的缓存,它不应该改变缓存行为:检查缓存,以确保所请求的对象是不是已经在缓存中,然后从数据库中加载并缓存它。改变方法GetPageById,实施后AspectF ,如下所示:

  public Page GetPageById(int pageId)

  {

  return AspectF.Define

  .Cache(_cacheResolver, CacheSetup.CacheKeys.PageId(pageId))

  .Return(() =>

  _database.GetSingle(DropthingsDataContext.SubsystemEnum.Page,

  pageId, LinqQueries.CompiledQuery_GetPageById).Detach());

  }

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

  它确认行为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);

原文转自:http://www.codeproject.com/Articles/44276/Unit-Testing-and-Integration-Testing-in-Business-A