我需要声明基类WorkItem
一次传递给一个方法,派生的SendEmailWorkItem
传递一次。
repo = new Mock<IWorkItemRepository>();
repo.Setup(x => x.Add(It.IsAny<WorkItem>())).Verifiable();
repo.Setup(x => x.Add(It.Is<SendEmailWorkItem>(wi => wi.ResponsibleId == responsibleGuid))).Verifiable();
Moq说,第一次期望发生两次,第二次期望发生0次。我理解这是因为类型在同一继承层次结构中。 (以下断言采用MSpec语法)
It should_add_new_claim_workitem = () => repo.Verify(x => x.Add(MockIt.IsAny<WorkItem>()), Times.Once());
It should_add_security_service_notification_workitem_with_same_responsible_as_new_claim = () => repo.Verify(x => x.Add(MockIt.Is<SendEmailWorkItem>(wi => wi.ResponsibleId == responsibleGuid)), Times.Once());
如何根据类型限制期望?
答案 0 :(得分:2)
以相反的顺序指定设置?
答案 1 :(得分:1)
使用It.Is<>
并检查类型:
namespace MoqTests
{
using Moq;
using NUnit.Framework;
public class WorkItem
{
public int Id { get; set; }
}
public class SendEmailWorkItem : WorkItem
{
public string ResponsibleId { get; set; }
}
public interface IWorkItemRepository
{
void Add(WorkItem workItem);
}
public class Worker
{
private readonly IWorkItemRepository repository;
public Worker(IWorkItemRepository repository)
{
this.repository = repository;
}
public void DoWork()
{
var workItem = new WorkItem{Id = 1};
repository.Add(workItem);
var emailWorkItem = new SendEmailWorkItem{Id = 2, ResponsibleId = "responsible"};
repository.Add(emailWorkItem);
}
}
[TestFixture]
public class MoqTest
{
[Test]
public void Should_add_WorkItem_and_SendEmailWorkItem()
{
//arrange
var repository = new Mock<IWorkItemRepository>(MockBehavior.Strict);
repository.Setup(r=>r.Add(It.Is<WorkItem>(item => item.GetType() == typeof(WorkItem)))).Verifiable();
repository.Setup(r=>r.Add(It.Is<SendEmailWorkItem>(item=>item.ResponsibleId == "responsible"))).Verifiable();
var worker = new Worker(repository.Object);
//act
worker.DoWork();
//assert
repository.Verify(r => r.Add(It.Is<WorkItem>(item => item.GetType() == typeof(WorkItem))), Times.Once());
repository.VerifyAll();
}
}
}
答案 2 :(得分:-1)
使用这种设置:
public interface IWorkItemRepository
{
void Add(WorkItem workItem);
IQueryable<WorkItem> GetAll();
void Finish(int workitemId);
}
public class WorkItem
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SendEmailWorkItem : WorkItem
{
public Guid ResponsibleId { get; set; }
}
这样可行,但可能不是最优雅的解决方案
[TestFixture]
public class WorkItemRepositoryTests
{
[Test]
public void Test()
{
// Arrange
var responsibleGuid = new Guid("11111111-2222-3333-4444-555555555555");
var workitemRepo = new Mock<IWorkItemRepository>();
workitemRepo.Setup(x => x.Add(It.IsAny<WorkItem>())).Verifiable();
workitemRepo.Setup(x => x.Add(It.Is<SendEmailWorkItem>(wi => wi.ResponsibleId == responsibleGuid))).Verifiable();
// Act
workitemRepo.Object.Add(new WorkItem() {Id = 1});
workitemRepo.Object.Add(new SendEmailWorkItem(){ResponsibleId = responsibleGuid});
// Assert
workitemRepo.Verify(x => x.Add(It.Is<WorkItem>(item => item.Id == 1 )), Times.Once());
workitemRepo.Verify(x => x.Add(It.Is<SendEmailWorkItem>(wi => wi.ResponsibleId == responsibleGuid)), Times.Once());
}
}