使用Moq - 问题

时间:2010-02-27 15:58:12

标签: unit-testing moq

我刚刚开始使用Moq ver(3.1)并且我已经阅读了博客,而且还有什么不是....无论如何......我想直到你弄脏手,你才会学到:)

好的,我正在测试......

  var newProduct = new Mock<IPartialPerson>();   
  newProduct.SetupGet(p => p.FirstName).Returns("FirstName");   
  newProduct.SetupGet(p => p.MiddleName).Returns("MiddleName");   
  newProduct.SetupGet(p => p.LastName).Returns("LastName");   
  newProduct.SetupGet(p => p.EmailAddress).Returns("EmailAddress@hotmail.com");   
  newProduct.SetupGet(p => p.UserID).Returns("UserID");   

  //mock Escort repository   
  var mockEscortRepository = new Mock<IEscortRepository>();     
  mockEscortRepository.Setup(p => p.LoadAllEscorts())   
      .Returns(newProduct.Object); //error  

  

错误1最佳重载方法   匹配   'Moq.Language.IReturns&GT; .Returns(System.Collections.Generic.List)'   有一些无效的论点


  

错误2参数'1':无法转换   从   'App.Model.Interface.IPartialPerson'   至   'System.Collections.Generic.List'


public interface IPartialPerson   
    {   
        string FirstName { get; }   
        string MiddleName { get; }   
        string LastName { get; }   
        string EmailAddress { get; }   
        string FullName { get; }   
        string UserID { get; }   

    }  

public interface IEscortRepository   
   {   
       List<PartialPerson> LoadAllEscorts();   
       List<PartialPerson> SelectedEscorts(List<PartialPerson> selectedEscorts);     
   }  

我有两种方法可以测试“LoadAllaEscorts”和“SelectedEscorts”

我将如何对这两种方法进行测试?

3 个答案:

答案 0 :(得分:5)

试试这个:

mockEscortRepository
.Setup(p => p.LoadAllEscorts())
.Returns(new List<IPartialPerson>() { newProduct.Object } ); 

当你说:

.Returns(newProduct.Object)

您要求Moq返回一个特定对象。编译器看到您的方法返回一个列表,因此除非您提供要返回的列表,否则它将无法编译。所以你需要创建一个包含你想要返回的对象的列表,然后让Moq返回它。

根据您的评论,您可能还有兴趣测试包含多个项目的列表。为此,创建一个包含多个项目的列表,然后让Mock返回该项目。以下是一种可以创建包含多个项目的列表的方法:

List<PartialPerson> escorts = new List<PartialPerson>();
for (int i = 0; i < 10; i++)
{

    var escort = new Mock<IPartialPerson>();
    escort.SetupGet(p => p.FirstName).Returns("FirstName" + i);
    escort.SetupGet(p => p.MiddleName).Returns("MiddleName" + i);
    escort.SetupGet(p => p.LastName).Returns("LastName" + i);
    escort.SetupGet(p => p.EmailAddress).Returns(i + "EmailAddress@hotmail.com");
    escort.SetupGet(p => p.UserID).Returns("UserID" + i);
    escorts.Add(escort.Object);
}

mockEscortRepository
    .Setup(p => p.LoadAllEscorts())
    .Returns(escorts); 

祝你好运并继续留在pimpin!

答案 1 :(得分:3)

  

我有两种方法可以测试   “LoadAllaEscorts”和   “SelectedEscorts”

这些是接口上的方法。您不会针对接口或模拟对象编写测试。您针对具体类编写测试。

某处你有一个实现IEscortRepository的EscortRepository。我假设它击中了数据库。针对该问题编写集成测试。

在代码的其他地方,你可能有一个类(称为“Foo”),它有一个IEscortRepository依赖注入其中(例如通过构造函数参数)。当您想针对Foo类编写测试时,您将使用Moq创建一个模拟IEscortRepository,返回固定的测试数据并将该模拟对象传递给您的Foo实例。

另一个问题是您的IEscortRepository方法正在返回(或作为参数)List&lt; PartialPerson&gt;。那些应该是IList&lt; IPartialPerson&gt; (或IEnumerable&lt; T&gt;,ICollection&lt; T&gt;或ReadOnlyCollection&lt; T&gt;)。最重要的部分是集合项应该是接口类型(IPartialPerson)。

+1为magnifico,谁拥有正确的代码:

using System;
using System.Collections.Generic;
using Moq;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var newProduct = new Mock<IPartialPerson>();

            newProduct.SetupGet(p => p.FirstName).Returns("FirstName");
            newProduct.SetupGet(p => p.MiddleName).Returns("MiddleName");
            newProduct.SetupGet(p => p.LastName).Returns("LastName");
            newProduct.SetupGet(p => p.EmailAddress).Returns("EmailAddress@hotmail.com");
            newProduct.SetupGet(p => p.UserID).Returns("UserID");

            var mockEscortRepository = new Mock<IEscortRepository>();

            mockEscortRepository
                .Setup(p => p.LoadAllEscorts())
                .Returns(new List<IPartialPerson> {newProduct.Object});

            IEscortRepository repository = mockEscortRepository.Object;

            IList<IPartialPerson> escorts = repository.LoadAllEscorts();

            foreach (IPartialPerson person in escorts)
            {
                Console.WriteLine(person.FirstName + " " + person.LastName);
            }

            Console.ReadLine();

            // Outputs "FirstName LastName"
        }
    }

    public interface IPartialPerson
    {
        string FirstName { get; }
        string MiddleName { get; }
        string LastName { get; }
        string EmailAddress { get; }
        string FullName { get; }
        string UserID { get; }
    }

    public interface IEscortRepository
    {
        IList<IPartialPerson> LoadAllEscorts();
        IList<IPartialPerson> SelectedEscorts(IList<IPartialPerson> selectedEscorts);
    }
}

(以上示例单元测试;它只是显示Moq有效。)

请注意,您不必将SetupGet用于属性;安装也有效。

答案 2 :(得分:1)

您的模型设置为返回单个项目,它应该根据存储库接口返回List。