繁体   English   中英

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

[英]Using moq to mock a repository for unit testing

我有以下票务库:

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
  }
}

现在,我想编写以下单元测试(单元测试的名称是“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 expression,Times times,Int32 callCount)Moq.Mock.VerifyCalls(Interceptor targetInterceptor,MethodCall expected,Expression expression,Times times)at at Moq.Mock.Verify [T](模拟1 mock, Expression 1表达式,时间时间,字符串failMessage)在Moq.Mock 1. 1.Verify(Expression 1表达式)
在TicketRepositoryTest.TicketRepositoryTest.TicketMoetCorrectGelezenWorden()中。\\ Eg_SupportCenter \\ TicketRepositoryTest \\ TicketRepositoryTest.cs:第41行结果消息:测试方法TicketRepositoryTest.TicketRepositoryTest.TicketMoetCorrectGelezenWorden抛出异常:Moq.MockException:模拟上的预期调用至少一次,但从未执行:l => l.Add(It.IsAny())未配置任何设置。 没有进行任何调用。

谁能告诉我我做错了什么? 使用Mock的TicketRepository:

 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();
        }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM