2009-08-02 60 views
3

我在Moq中遇到了一些奇怪的行为 - 尽管事实上我设置了一个模拟对象以某种方式行动,然后以确切的方式调用该方法在我测试的对象中以相同的方式进行反应,就好像该方法从未被调用一样。模拟对象的期望看起来不符合(Moq)

我有我想测试下的控制器操作:

public ActionResult Search(string query, bool includeAll) 
{ 
    if (query != null) 
    { 
     var keywords = query.Split(' '); 
     return View(repo.SearchForContacts(keywords, includeAll)); 
    } 
    else 
    { 
     return View(); 
    } 
} 

我的单元测试代码:

public void SearchTestMethod() // Arrange 
    var teststring = "Anders Beata"; 
    var keywords = teststring.Split(' '); 
    var includeAll = false; 
    var expectedModel = dummyContacts.Where(c => c.Id == 1 || c.Id == 2); 
    repository 
     .Expect(r => r.SearchForContacts(keywords, includeAll)) 
     .Returns(expectedModel) 
     .Verifiable(); 

    // Act 
    var result = controller.Search(teststring, includeAll) as ViewResult; 

    // Assert 
    repository.Verify(); 
    Assert.IsNotNull(result); 
    AssertThat.CollectionsAreEqual<Contact>(
     expectedModel, 
     result.ViewData.Model as IEnumerable<Contact> 
    ); 
} 

其中AssertThat就是一个类我自己和一帮断言助手(因为Assert类不能用扩展方法扩展......叹息......)。

当我运行测试,它无法在repository.Verify()线,具有MoqVerificationException

Test method MemberDatabase.Tests.Controllers.ContactsControllerTest.SearchTestMethod() 
threw exception: Moq.MockVerificationException: The following expectations were not met: 
IRepository r => r.SearchForContacts(value(System.String[]), False)

如果我删除repository.Verify(),收集断言失败告诉我,返回的模式是null。我已调试并检查了query != null,并将其带入运行代码的if块的一部分。那里没有问题。

为什么不能正常工作?

回答

6

我怀疑是因为你传入你的模拟仓库(teststring.Split(' ')的结果)的数组与实际从搜索方法传入的数组(query.Split(' ')的结果)不同。

尝试更换你的设置代码的第一行:

repository.Expect(r => r.SearchForContacts(
    It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll)) 

...这将传递给你的模拟与keywords数组中的相应元素的数组中的每个元素进行比较。

+0

谢谢!那就马上做了这个伎俩! =)看来我必须阅读Moq,特别是何时以及如何使用It ...结构。 – 2009-08-02 22:51:28