Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试和moq工作显示异常:以下设置不匹配:_C#_Visual Studio 2012_Moq - Fatal编程技术网

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

C# 单元测试和moq工作显示异常:以下设置不匹配:,c#,visual-studio-2012,moq,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 Li

我正在使用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();
        }
    }
}
单元测试:

[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);

    }
}
[TestClass]
公共类SomeUtilTest
{
模拟适配器;
列出人员名单;
SomeUtil-util;
[测试初始化]
公共无效初始化()
{
适配器=新模拟();
人员=新列表();
util=新的SomeUtil();
}
[测试清理]
公共空间清理()
{
adapter.VerifyAll();
}
[测试方法]
public void Valid_with emptyName_ShouldRemove()
{
Person=新人();
person.Gender=“”;
人,年龄=1;
人。添加(人);
人员结果=新人员();
结果:年龄=19岁;
结果:性别=“女性”;
result.Name=“Dannie”;
Setup(a=>a.SetGender(person)).Returns(result);
int count=人。计数;
实用有效(人);
断言.AreEqual(计数-1,个人数);
}
}
因为您新创建了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);
    }
[测试初始化]
公共无效初始化()
{
适配器=新模拟();
人员=新列表();
util=newsomeutil(adapter.Object);
}
然而,理想情况下,您不会模拟和注入一个实体类,而是一个接口或抽象类型。另外,在您的应用程序(而不是测试)中,您可能会希望使用像Ninject或Windsor这样的DI框架(自从我使用.NET已经有一段时间了,所以现在可能有不同的选项)

克里斯

因为您新创建了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);
    }
[测试初始化]
公共无效初始化()
{
适配器=新模拟();
人员=新列表();
util=newsomeutil(adapter.Object);
}
然而,理想情况下,您不会模拟和注入一个实体类,而是一个接口或抽象类型。另外,在您的应用程序(而不是测试)中,您可能会希望使用像Ninject或Windsor这样的DI框架(自从我使用.NET已经有一段时间了,所以现在可能有不同的选项)


Chris

这是因为您的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);
    }
[测试初始化]
公共无效初始化()
{
适配器=新模拟();
人员=新列表();
util=newsomeutil(adapter.Object);
}
注意
adapter.Object
的用法。这将为您提供Moq观察到的类的实例


如果您进行了这些更改,您的单元测试将通过。但这里有一个更深层次的基本原则,我鼓励你们研究一下。在许多事情中,它使使用模拟测试库更加容易。

这是因为您的SomeUtil类使用的是真正的SomeAdapter类,而不是模拟类。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);
    }
[测试初始化]
公共无效初始化()
{
适配器=新模拟();
人员=新列表();
util=newsomeutil(adapter.Object);
}
注意
adapter.Object
的用法。这将为您提供Moq观察到的类的实例


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

Owen,这不是编译。Mock不能直接转换为SomeAdapter。很抱歉,正如我说的,我已经有一段时间没有使用.NET了,您需要直接传递Mock,而不是传递Mock。对象根据,我现在编辑Owen,这不会编译。Mock不能直接转换为SomeAdapter。很抱歉,正如我所说,我已经有一段时间没有使用.NET了,您需要直接传递Mock.Object,而不是传递Mock.Object。根据,我现在编辑很好,给出了与我完全相同的答案,只是我忘了传递Mock.Object。很好的回答。很抱歉,我注意到你在同一时间发布了帖子,以为这只是一个拷贝/过去,只是做了一些轻微的修改工作。我收回这句话,先生,我会投你一票:)你真的赢了我。我应该打得快一点。:)我对你的答案投了更高的票。做得好,给出了与我完全相同的答案,只是我忘了在Mock.Object中通过。很好的回答。很抱歉,我注意到你在同一时间发布了帖子,以为这只是一个拷贝/过去,只是做了一些轻微的修改工作。我收回这句话,先生,我会投你一票:)你真的赢了我。我应该打得快一点。:)我对你的答案投了赞成票。