unit-testing - 我可以对进行 Sitecore 上下文调用的方法进行单元测试吗?

标签 unit-testing nunit mstest sitecore sitecore6

我正在开发基于 Sitecore CMS 构建的 Web 应用程序。我想知道我们是否可以对例如从 Sitecore 获取一些数据的方法进行单元测试并对其进行一些处理并输出结果。我想通过单元测试来测试方法中的所有逻辑。

在广泛深入地搜索互联网后,我感到非常困惑。有人说这种测试实际上是集成测试而不是单元测试,我应该只测试没有 Sitecore 调用的代码,其他人说这是不可能的,因为 Sitecore 上下文会丢失。

我想请有经验的程序员同行帮忙:
我可以对包含 Sitecore 调用的方法进行单元测试吗?如果是,如何?如果否,为什么?有什么解决方法吗?

该项目处于起步阶段,因此如果解决方案与选择的单元测试框架相关,那么在 MSTest 或 Nunit 等单元测试框架之间进行选择是没有问题的。

最佳答案

如果不提供电子邮件并通过销售宣传,很难找到有关 Sitecore 的任何信息,因此我将提供一个通用方法来说明如何执行此类操作。

首先,您假设 Sitecore API 可以保证工作 - 即它是一个框架 - 而且您不进行单元测试 .您应该对与它的交互进行单元测试。

然后,download MOQ并阅读 quick start on how to use it .这是我首选的模拟框架。如果您愿意,请随意使用其他框架。

希望 Sitecore API 为您提供了一种无需处理持久性即可创建数据对象的方法 - 即简单地创建您感兴趣的任何内容的新实例。这是我想象的 API:

public class Post {
  public string Body {get;set;}
  public DateTime LastModified {get;set;}
  public string Title {get;set;}
}

public interface ISiteCorePosts {
  public IEnumerable<Post> GetPostsByUser(int userId);
}

在这种情况下,单元测试应该相当容易。通过一些依赖注入(inject),您可以将 SiteCore 接口(interface)注入(inject)到您的组件中,然后对其进行单元测试。

public class MyPostProcessor {

  private readonly ISiteCorePosts m_postRepository;

  public MyPostProcessor(ISiteCorePosts postRepository) {
    m_postRepository = postRepository;
  }

  public void ProcessPosts(int userId) {
     var posts = m_postRepository.GetPostsByUser(userId);
     //do something with posts
  }
}

public class MyPostProcessorTest {
  [TestMethod]
  ProcessPostsShouldCallGetPostsByUser() {
    var siteCorePostsMock = new Mock<ISiteCorePosts>();
    //Sets up the mock to return a list of posts when called with userId = 5
    siteCorePostsMock.Setup(m=>m.GetPostsByUser(5)).Returns(new List<Post>{/*fake posts*/});

    MyPostProcessor target = new MyPostProcessor(siteCorePostsMock.Object);
    target.ProcessPosts(5);
    //Verifies that all setups are called
    siteCorePostsMock.VerifyAll();
  }
}

如果 ISiteCorePosts实际上,它不是一个接口(interface),而是一个具体的类,它的方法不是虚拟的,因此不能被模拟,你需要使用 Facade pattern包装 SiteCore 交互以使其对测试更加友好。

public class SiteCorePostsFacade {

  SiteCorePosts m_Posts = new SiteCorePosts();

  //important - make this method virtual so it can be mocked without needing an interface
  public virtual IEnumerable<Post> GetPostsByUser(int userId) {
    return m_Posts.GetPostsByUser(userId);
  }
}

然后继续使用 SiteCorePostsFacade就好像它是前面示例中的接口(interface)一样。 MOQ 的好处是它允许您使用虚拟方法模拟具体类,而不仅仅是接口(interface)。

使用这种方法,您应该能够将各种数据注入(inject)您的应用程序,以测试与 SiteCore API 的所有交互。

关于unit-testing - 我可以对进行 Sitecore 上下文调用的方法进行单元测试吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3231457/

相关文章:

unit-testing - 如何开始单元测试或TDD?

testing - 在单元测试中使用依赖注入(inject)对象是个坏主意吗?

.net - MSTest:断言线程执行

java - 如何模拟由MyBatis初始化的接口(interface)的引用?

php - 使用抽象参数实例化对象

c# - 使用 Rhino 从模拟对象引发事件

unit-testing - 如何有效地对使用 ADO.NET 和 SQL Server 和 NUnit 的 DAL 进行单元测试?

mstest - 如何指示 MSTest 在测试运行后删除所有测试工件?

c# - 没有执行 msTest 的测试

php - 如何在 PHPUnit 中 stub 更复杂的方法