我正在开发基于 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/