C# 单元测试和moq工作显示异常:以下设置不匹配:
我正在使用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
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中通过。很好的回答。很抱歉,我注意到你在同一时间发布了帖子,以为这只是一个拷贝/过去,只是做了一些轻微的修改工作。我收回这句话,先生,我会投你一票:)你真的赢了我。我应该打得快一点。:)我对你的答案投了赞成票。