2012-05-02 104 views
5

我剛剛開始使用RavenDB,並且我喜歡它。然而,我堅持如何單元測試控制器與其交互的操作。ASP.NET MVC,RavenDb和單元測試

我已經找到像這樣的所有問題/文章:Unit testing RavenDb queries告訴我我應該在內存中使用RavenDB而不是模擬它,但我找不到一個如何做到這一點的可靠示例。

比如我有一個控制器動作給員工添加到數據庫中(是的,這是過於簡單,但我不想節外生枝)

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"); 
    } 

我如何驗證什麼加入數據庫在單元測試中?有沒有人有MVC應用程序中涉及RavenDb的單元測試的例子?

我使用MSTest如果重要,但我很樂意嘗試翻譯來自其他框架的測試。

謝謝。

編輯

好吧,我測試的initialise創建注入的控制器構造文檔存儲,但是當我運行我的測試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. 
    } 
} 

我錯過了什麼?我如何獲得在測試中創建的會話?

+0

我已經更新了我的問題,請參見下面 –

回答

7

運行單元測試後,只需聲明數據庫中有一個新文檔,並且它已設置正確的字段。

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

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

RavenDB內存模式是存在的,這樣你就不必嘲笑它,你只需做到以下幾點:

  • 打開新 - 內存嵌入式文檔存儲(無數據)
  • 如果需要插入單元測試運行所需的任何數據
  • RUN th E單元測試
  • 看在內存存儲中的數據,看看它。如果你想有一個完整的樣本已被正確

更新更新,看看在RacoonBlog代碼是怎麼做的,這是運行Ayende's blog的代碼。見這2個文件:

+0

是的,我正在尋找一個更完整的例子,因爲我已經得到了很多:)查看我的問題以獲取更多信息。 – Nick

3

我如何驗證什麼加入到數據庫在單元測試?

你不知道。我們不在單元測試中測試這些東西。這是集成測試的責任,而不是單元測試。

如果你想單元測試依賴於某些外部源(如你的數據庫)的類,模擬數據庫訪問。

編輯:

糾正一些錯誤提到,我會從MSDN引用定義(但所有其他資源同意這一點):

單元測試的主要目標是將這是應用程序中最小的 可測試軟件,將其與 代碼的其餘部分隔離,並確定其行爲是否與您期望的完全相同。

沒有嘲笑你忽略了單元測試的基本原則 - 隔離和測試儘可能最小的一塊。單元測試需要持久不變,不應該依賴於某些外部類。如果數據庫隨時間變化會怎樣?重寫所有測試,即使功能保持完全一樣?

來吧。你可以給我多少次你想要的,但這不會讓你變得正確。

+2

這是真的,但RavenDB的內存模式,使得它很容易做集成測試,你經常不需要麻煩做單元測試和嘲笑所有的東西 –

+1

@MattWarren,嗯,我認爲我們正在編寫測試是持久的 - 無知的......這不是一個關於它是否容易的問題。單元測試不應該超出課程界限,否則將會是一個集成測試。無論你是在內存,文件還是在完全不同的服務器上都有db。原則保持不變...恐怕... – walther

+0

通常使用像SQL Server這樣的RDBMS我會有一個倉庫併爲這些測試進行模擬。然而,我在RavenDB上閱讀的所有文章,包括Ayende的博客,都說不要這樣做......所以我想我會試試它。 – Nick