使用moq模拟存储库以进行单元测试

时间:2017-03-12 14:52:28

标签: c# unit-testing moq

我有以下故障单存储库:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Moq;
using SC.BL.Domain;

namespace SC.DAL
{
  public class TicketRepositoryHC : ITicketRepository
  {
    private List<Ticket> tickets;
    private List<TicketResponse> responses;
    private Mock<IList<Ticket>> ticketsMock;

    public TicketRepositoryHC()
    {
      Seed();
    }

    public TicketRepositoryHC(Mock<IList<Ticket>> ticketsMock)
    {
        this.ticketsMock = ticketsMock;
        Seed();
    }

    private void Seed()
    {
      tickets = new List<Ticket>();
      responses = new List<TicketResponse>();

      // Aanmaken eerste ticket met drie responses
      Ticket t1 = new Ticket()
      {
        TicketNumber = tickets.Count + 1,
        AccountId = 1,
        Text = "Ik kan mij niet aanmelden op de webmail",
        DateOpened = new DateTime(2012, 9, 9, 13, 5, 59),
        State = TicketState.Closed,
        Responses = new List<TicketResponse>()
      };

      tickets.Add(t1);

      TicketResponse t1r1 = new TicketResponse()
      {
        Id = responses.Count + 1,
        Ticket = t1,
        Text = "Account is geblokkeerd",
        Date = new DateTime(2012, 9, 9, 13, 24, 48),
        IsClientResponse = false
      };
      t1.Responses.Add(t1r1);
      responses.Add(t1r1);

      TicketResponse t1r2 = new TicketResponse()
      {
        Id = responses.Count + 1,
        Ticket = t1,
        Text = "Account terug in orde en nieuw paswoord ingesteld",
        Date = new DateTime(2012, 9, 9, 13, 29, 11),
        IsClientResponse = false
      };
      t1.Responses.Add(t1r2);
      responses.Add(t1r2);

      TicketResponse t1r3 = new TicketResponse()
      {
        Id = responses.Count + 1,
        Ticket = t1,
        Text = "Aanmelden gelukt en paswoord gewijzigd",
        Date = new DateTime(2012, 9, 10, 7, 22, 36),
        IsClientResponse = true
      };
      t1.Responses.Add(t1r3);
      responses.Add(t1r3);

      t1.State = TicketState.Closed;


      //Aanmaken tweede ticket met één response
      Ticket t2 = new Ticket()
      {
        TicketNumber = tickets.Count + 1,
        AccountId = 1,
        Text = "Geen internetverbinding",
        DateOpened = new DateTime(2012, 11, 5, 9, 45, 13),
        State = TicketState.Open,
        Responses = new List<TicketResponse>()
      };

      tickets.Add(t2);

      TicketResponse t2r1 = new TicketResponse()
      {
        Id = responses.Count + 1,
        Ticket = t2,
        Text = "Controleer of de kabel goed is aangesloten",
        Date = new DateTime(2012, 11, 5, 11, 25, 42),
        IsClientResponse = false
      };
      t2.Responses.Add(t2r1);
      responses.Add(t2r1);

      t2.State = TicketState.Answered;

      //Aanmaken eerste HardwareTicket
      HardwareTicket ht1 = new HardwareTicket()
      {
        TicketNumber = tickets.Count + 1,
        AccountId = 2,
        Text = "Blue screen!",
        DateOpened = new DateTime(2012, 12, 14, 19, 15, 32),
        State = TicketState.Open,
        //Responses = new List<TicketResponse>(),
        DeviceName = "PC-123456"
      };

      tickets.Add(ht1);
    }

    #region 'ITicketRepository' implementatie
    public Ticket CreateTicket(Ticket ticket)
    {
      ticket.TicketNumber = tickets.Count + 1;
      tickets.Add(ticket);

      return ticket; //return van ticket testen, niet ReadTicket gebruiken
    }

    public IEnumerable<Ticket> ReadTickets()
    {
      return tickets;
    }

    public Ticket ReadTicket(int ticketNumber)
    {
      return tickets.Find(t => t.TicketNumber == ticketNumber);
    }

    public void UpdateTicket(Ticket ticket)
    {
      // Do nothing! All data lives in memory, everything references the same objects!!
    }

    public void DeleteTicket(int ticketNumber)
    {
      this.responses.RemoveAll(r => r.Ticket.TicketNumber == ticketNumber);
      this.tickets.Remove(ReadTicket(ticketNumber));
    }

    public IEnumerable<TicketResponse> ReadTicketResponsesOfTicket(int ticketNumber)
    {
      return tickets.Find(t => t.TicketNumber == ticketNumber).Responses;
    }

    public TicketResponse CreateTicketResponse(TicketResponse response)
    {
      response.Id = responses.Count + 1;
      responses.Add(response);
      return response;
    }
    #endregion
  }
}

现在,我想编写以下单元测试(单元测试的名称是&#34; TicketHasToBeReadCorrectly,我只想测试是否可以正确读取已添加到存储库的故障单:

namespace TicketRepositoryTest
{
    [TestClass]
    public class TicketRepositoryTest
    {
        [TestMethod]
        public void TicketMoetCorrectGelezenWorden()
        {
            //Arrange

            var ticketsMock = new Mock<IList<Ticket>>();

            ITicketRepository ticketRepo = new TicketRepositoryHC(ticketsMock);

            //Act

            Ticket ticket = new Ticket() {
                //TicketNumber = 2,
                AccountId = 1,
                Text = "Ik kan mij niet aanmelden op de webmail",
                DateOpened = new DateTime(2012, 9, 9, 13, 5, 59),
                State = TicketState.Open,
                Responses = new List<TicketResponse>()
            };

            var returnTicket = ticketRepo.CreateTicket(ticket);


            //Assert
            ticketsMock.Verify(l => l.Add(It.IsAny<Ticket>()));
            Assert.ReferenceEquals(ticket, returnTicket);
            Assert.IsTrue(ticket.TicketNumber != default(int));

        }
    }
}

但是此测试失败并显示以下消息:

  

测试名称:TicketMoetCorrectGelezenWorden测试   FullName:TicketRepositoryTest.TicketRepositoryTest.TicketMoetCorrectGelezenWorden   测试   来源:.Eg_SupportCenter \ TicketRepositoryTest \ TicketRepositoryTest.cs   :第19行测试结果:失败的测试持续时间:0:00:00,0388466

     

结果StackTrace:在Moq.Mock.ThrowVerifyException(MethodCall   预期,IEnumerable 1 setups, IEnumerable 1 actualCalls,Expression   表达式,Times times,Int32 callCount)at   Moq.Mock.VerifyCalls(Interceptor targetInterceptor,MethodCall   预期,表达式,时间)   Moq.Mock.Verify [T](模拟1 mock, Expression 1表达式,时间时间,   字符串failMessage)在Moq.Mock 1.Verify(Expression 1表达式)
  在   TicketRepositoryTest.TicketRepositoryTest.TicketMoetCorrectGelezenWorden()   在   \ Eg_SupportCenter \ TicketRepositoryTest \ TicketRepositoryTest.cs:行   41结果消息:测试方法   TicketRepositoryTest.TicketRepositoryTest.TicketMoetCorrectGelezenWorden   抛出异常:Moq.MockException:模拟上的预期调用   至少一次,但从未进行过:l =&gt; l.Add(It.IsAny())   没有配置设置。没有进行调用。

有谁能告诉我我做错了什么? TicketRepository with Mock:

 public class TicketRepositoryHC : ITicketRepository
  {
    private List<Ticket> tickets;
    private List<TicketResponse> responses;
    private Mock<IList<Ticket>> ticketsMock;

        public TicketRepositoryHC()
    {
      Seed();
    }

        public TicketRepositoryHC(Mock<IList<Ticket>> ticketsMock)
        {
            this.ticketsMock = ticketsMock;
            Seed();
        }

1 个答案:

答案 0 :(得分:0)

从存储库中取出所有模拟内容。这是错的。创建类型为TicketRepositoryHC的模拟版本,并使用Moq的Setup()来模拟您的方法,ReadTicketResponsesOfTicket()等。