简体   繁体   English

ASP.NET MVC,RavenDb和单元测试

[英]ASP.NET MVC, RavenDb and Unit Testing

I'm just getting started with RavenDB and I like it so far. 我刚刚开始使用RavenDB,到目前为止我还喜欢它。 I am however stuck on how I should unit test controller actions that interact with it. 然而,我仍然坚持如何单元测试与之交互的控制器操作。

All the questions/articles I have found like this one: Unit testing RavenDb queries tell me I should use RavenDB in memory rather than mock it away but I cannot find a solid example of how this is done. 我发现的所有问题/文章都是这样的: 单元测试RavenDb查询告诉我应该在内存中使用RavenDB而不是嘲笑它但是我找不到一个如何完成的实例。

For example I have a controller action to add an employee to the database (yes, it's overly simplified but I don't want to complicate the issue) 例如,我有一个控制器操作将员工添加到数据库(是的,它过于简化,但我不想让问题复杂化)

public class EmployeesController : Controller
{

  IDocumentStore _documentStore;
  private IDocumentSession _session;

  public EmployeesController(IDocumentStore documentStore)
  {
    this._documentStore = documentStore;

  }

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    _session = _documentStore.OpenSession("StaffDirectory");
  }

  protected override void OnActionExecuted(ActionExecutedContext filterContext)
  {
      if (_session != null && filterContext.Exception == null) {
        _session.SaveChanges();
        _session.Dispose();
    }
  }

  [HttpGet]
  public ViewResult Create()
  {
    return View();
  }

  [HttpPost]
  public RedirectToRouteResult Create(Employee emp)
  {
    ValidateModel(emp);
    _session.Store(emp);
    return RedirectToAction("Index");
  }

How can I verify what was added to the database in a unit test? 如何在单元测试中验证添加到数据库的内容? Does anyone have any examples of unit tests involving RavenDb in MVC applications? 有没有人在MVC应用程序中有任何涉及RavenDb的单元测试的例子?

I'm using MSTest if that matters but I'm happy to try and translate tests from other frameworks. 我正在使用MSTest,如果这很重要,但我很乐意尝试从其他框架中翻译测试。

Thanks. 谢谢。

EDIT 编辑

Ok, my test initialise creates the document store that is injected into the controller constructor, but when I run my test the OnActionExecuting event doesn't run so there is no session to use and the test fails with a null reference exception. 好吧,我的测试初始化​​创建了注入控制器构造函数的文档存储,但是当我运行测试时,OnActionExecuting事件没有运行,所以没有会话要使用,测试失败并带有空引用异常。

[TestClass]
public class EmployeesControllerTests
{
  IDocumentStore _store;

  [TestInitialize]
  public void InitialiseTest()
  {
    _store = new EmbeddableDocumentStore
    {
      RunInMemory = true
    };
    _store.Initialize();
  }

  [TestMethod]
  public void CreateInsertsANewEmployeeIntoTheDocumentStore()
  {
    Employee newEmp = new Employee() { FirstName = "Test", Surname = "User" };

    var target = new EmployeesController(_store);
    ControllerUtilities.SetUpControllerContext(target, "testUser", "Test User", null);

    RedirectToRouteResult actual = target.Create(newEmp);
    Assert.AreEqual("Index", actual.RouteName);

    // verify employee was successfully added to the database.
  }
}

What am I missing? 我错过了什么? How do I get the session created to use in the test? 如何创建在测试中使用的会话?

After you've run your unit test, just assert that there is a new doc in the database and that it has the right fields set. 运行单元测试后,只需声明数据库中有新文档,并且设置了正确的字段。

var newDoc = session.Load<T>(docId)

or 要么

var docs = session.Query<T>.Where(....).ToList();

RavenDB in-memory mode is there so that you don't have to mock it out, you just do the following: RavenDB内存模式是存在的,所以你不必嘲笑它,你只需要执行以下操作:

  • Open a new in-memory embedded doc store (with no data) 打开一个新的内存嵌入式doc存储(没有数据)
  • If needed insert any data your unit test needs to run 如果需要,请插入单元测试需要运行的任何数据
  • RUN the unit test 运行单元测试
  • Look at the data in the in-memory store and see if it has been updated correctly 查看内存存储中的数据,看看它是否已正确更新

Update If you want a full sample, take a look at how the RacoonBlog code does it, this is the code running Ayende's blog . 更新如果您需要完整示例,请查看RacoonBlog代码如何执行此操作,这是运行Ayende博客的代码。 See these 2 files: 看到这两个文件:

How can I verify what was added to the database in a unit test? 如何在单元测试中验证添加到数据库的内容?

You don't. 你没有。 We don't test such things in unit tests. 我们不在单元测试中测试这些东西。 This is a responsibility for integration tests, NOT unit testing. 这是集成测试的责任,而不是单元测试。

If you want to unit test classes, which depend on some external source (like your db), mock the database access. 如果要单元测试类(依赖于某些外部源(如数据库)),请模拟数据库访问。

EDIT: 编辑:

To correct some mentioned mistakes, I'll quote definition from MSDN (however all other resources agree with that): 为了纠正一些提到的错误,我将引用MSDN的定义(但所有其他资源都同意这一点):

The primary goal of unit testing is to take the smallest piece of testable software in the application, isolate it from the remainder of the code, and determine whether it behaves exactly as you expect. 单元测试的主要目标是在应用程序中使用最小的可测试软件,将其与代码的其余部分隔离,并确定其行为是否与您期望的完全相同。

Without mocking you are ignoring the basic principles of Unit testing - isolation and testing the smallest piece possible. 没有嘲笑你忽略了单元测试的基本原则 - 隔离和测试可能的最小部分。 Unit test need to be persistent-ignorant and shouldn't be relying on some external class. 单元测试需要持久无知,不应该依赖于某些外部类。 What if the db changes over time? 如果数据库随时间变化怎么办? Rewrite all tests, even though the functionality stays exactly the same? 重写所有测试,即使功能保持完全相同?

COME ON. 来吧。 You can give me -1 how many times you want, but that won't make you right. 你可以给我-1你想要多少次,但这不会让你正确。

As that thread you linked to mentioned use the EmbeddableDocumentStore by embedding RavenDB. 由于您链接到的那个线程通过嵌入RavenDB使用EmbeddableDocumentStore。

Here's how to set that up: http://msdn.microsoft.com/en-us/magazine/hh547101.aspx 以下是如何进行设置: http//msdn.microsoft.com/en-us/magazine/hh547101.aspx

Here's how to use the repository pattern with raven, so you can test easily: http://novuscraft.com/blog/ravendb-and-the-repository-pattern 以下是如何将存储库模式与raven一起使用,以便您可以轻松地进行测试: http//novuscraft.com/blog/ravendb-and-the-repository-pattern

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM