2012-02-13 30 views
2

我有下面的代码,我需要帮助编写一个单元测试。我正在使用Moq库。Moq - 如何验证方法调用哪个参数已被清除(列表)

这是交易。我有一个业务类与一个存储库(接口)的依赖关系,所以我可以用它来保存我的实体到数据库。我的实体基本上是一个字符串列表。来自MyBusinessClass的方法AddAndSave获取它接收到的值作为参数,将它放入列表并从IRepository调用Save方法。然后,我清除我的实体列表。下面的代码显示了这个例子(我已经简化了,所以我可以在这里解释它)。

还有一个单元测试。

using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Moq; 

namespace TestesGerais 
{ 
    public class MyEntity 
    { 
     public MyEntity() 
     { 
      MyList = new List<string>(); 
     } 
     public List<string> MyList { get; set; } 
    } 

    public interface IRepository 
    { 
     void Save(MyEntity entity); 
    } 

    public class MyBusinessClass 
    { 
     public IRepository Repository { get; set; } 
     private MyEntity _entity = new MyEntity(); 
     public void AddAndSave(string info) 
     { 
      _entity.MyList.Add(info); 
      Repository.Save(_entity); 
      _entity.MyList.Clear(); // for some reason I need to clear it 
     } 
    } 

    [TestClass] 
    public class UnitTest10 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      var mock = new Mock<IRepository>(); 
      MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object }; 
      b.AddAndSave("xpto"); 
      mock.Verify(m => m.Save(It.Is<MyEntity>(x => x.MyList[0] == "xpto")), Times.Exactly(1)); 
     } 
    } 
} 

我的单元测试检查,如果IRepository的保存方法,被称为具有列表中的一个元素,且在此元素的值“xpto”它的参数(实体)。

当我运行这个测试,它会变成红色并显示错误消息“测试方法TestesGerais.UnitTest10.TestMethod1抛出异常: System.ArgumentOutOfRangeException:索引超出范围必须大于大小非负少。集合 参数名称:索引“。

好的,这是由已清理的列表引起的。如果我评论“_entity.MyList.Clear();”这行,那么一切顺利。我的问题是:我如何测试这个没有评论我的业务类中的“清除”行,并确保我的存储库的方法被称为传递特定的值(一个元素的值为“xpto”)的实体?

谢谢

回答

1

我改变了我的单元测试使用Moq的回调功能。这样,我可以设置模拟,所以当AddAndSave被调用时,它接收到的参数被保存到我的单元测试中的一个变量中,我可以在稍后声明它。

[TestMethod] 
    public void TestMethod1() 
    { 
     var mock = new Mock<IRepository>(); 
     string result = string.Empty; 
     mock.Setup(m => m.Save(It.IsAny<MyEntity>())).Callback((MyEntity e) => { result = e.MyList[0]; }); 
     MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object }; 
     b.AddAndSave("xpto"); 
     Assert.AreEqual(result, "xpto"); 
    } 
+0

+1不错的解决方案 – 2012-02-14 13:18:11

0

你可以分开你的方法了一下。 “AddAndSave”并不是全部。然后您可以单独测试添加和保存位的行为。

+0

感谢您的建议,安东尼,但方法AddAndSave是一个合同,我不想现在打破,我需要测试它的功能。但是,在这种情况下,我得到了一个让Moq工作的诀窍,我会把它放在这里。 – Fabio 2012-02-14 12:50:25

相关问题