单元测试和moq工作显示异常:以下设置不匹配:

时间:2013-12-17 17:03:10

标签: c# visual-studio-2012 moq

我正在使用moq,但无法进行verifyAll方法调用。我不知道我做错了什么。

要测试的类:

namespace ConsoleApplication2
{
    public class SomeUtil
    {
        public static List<Person> underAgePerson = new List<Person>();

        public static List<Person> females = new List<Person>();

        public static List<Person> males = new List<Person>();

        public static List<Person> deletePersons = new List<Person>();

        public SomeAdapter adapter;

        public SomeUtil()
        {
            this.adapter = new SomeAdapter();
        }

        public void Valid(List<Person> persons)
        {
            foreach (Person p in persons)
            {
                if (p.Name == null)
                {
                    deletePersons.Add(p);
                }

                if (p.Age < 18)
                {
                    if (!deletePersons.Contains(p))
                    {
                        deletePersons.Add(p);
                    }
                    underAgePerson.Add(p);
                }
                adapter.SetGender(p);
                if (p.Gender.Equals("Male", StringComparison.InvariantCultureIgnoreCase))
                {
                    males.Add(p);
                }

                else if (p.Gender.Equals("Female", StringComparison.InvariantCultureIgnoreCase))
                {
                    females.Add(p);
                }
            }

            foreach (Person p in deletePersons)
            {
                persons.Remove(p);
            }
            deletePersons.Clear();
        }
    }
}

SomeUtil类:

namespace ConsoleApplication2
{
    public class SomeAdapter
    {
        public virtual Person SetGender(Person p)
        {
            if (string.IsNullOrEmpty(p.Gender))
            {
                p.Gender = "Male";
            }
            return p;
        }
    }
}

单元测试:

[TestClass]
public class SomeUtilTest
{
    Mock<SomeAdapter> adapter;
    List<Person> persons;
    SomeUtil util;
    [TestInitialize]
    public void Initialize()
    {
        adapter = new Mock<SomeAdapter>();
        persons = new List<Person>();
        util = new SomeUtil();
    }

    [TestCleanup]
    public void CleanUp()
    {
        adapter.VerifyAll();
    }

    [TestMethod]
    public void Valid_WithEmptyName_ShouldRemove()
    {
        Person person = new Person();
        person.Gender = "";
        person.Age = 1;
        persons.Add(person);

        Person result = new Person();
        result.Age = 19;
        result.Gender = "Female";
        result.Name = "Dannie";

        adapter.Setup(a => a.SetGender(person)).Returns(result);
        int count = persons.Count;
        util.Valid(persons);

        Assert.AreEqual(count - 1, persons.Count);

    }
}

2 个答案:

答案 0 :(得分:2)

    public SomeUtil()
    {
        this.adapter = new SomeAdapter();
    }

因为你有新的SomeAdapter而没有注入SomeUtil类,所以你要验证的模拟不是代码中与之交互的实例,它是一个完全不同的对象。

您需要通过构造函数或属性注入以某种方式注入SomeAdapter依赖项。您可以手动执行此操作,例如

在SomeUtil.cs

    public SomeUtil(SomeAdaptor adaptor)
    {
        this.adapter = adaptor;
    }

在测试设置中:

    [TestInitialize]
    public void Initialize()
    {
        adapter = new Mock<SomeAdapter>();
        persons = new List<Person>();
        util = new SomeUtil(adapter.Object);
    }

然而,理想情况下,您不会嘲笑和注入实体类,而是接口或抽象类型。此外,在您的应用程序(而不是测试)中,您可能希望使用像Ninject或Windsor这样的DI框架(自从我做.NET以来已经有一段时间了,所以现在可能有不同的选项)。

克里斯

答案 1 :(得分:2)

这是因为您的SomeUtil类使用的是真正的SomeAdapter类,而不是Mock类。 Moq无法观察真实类中方法的用法。

您需要做的是将SomeAdapter的实例注入SomeUtil类。而不是:

    public SomeAdapter adapter;
    public SomeUtil()
    {
        this.adapter = new SomeAdapter();
    }

这样做:

    public SomeAdapter adapter;
    public SomeUtil(SomeAdapter adapter)
    {
        this.adapter = adapter;
    }

然后,在单元测试中:

    [TestInitialize]
    public void Initialize()
    {
        adapter = new Mock<SomeAdapter>();
        persons = new List<Person>();
        util = new SomeUtil(adapter.Object);
    }

请注意adapter.Object的使用。这为您提供了Moq观察到的类的实例。

如果您进行了这些更改,您的单元测试将通过。但是dependency inversion这里有一个更深层次的基本原则,我鼓励你去研究。在许多方面,它使得使用模拟测试库更容易使用。