gpt4 book ai didi

c# - 使用 Moq 更新、删除单元测试的方法

转载 作者:太空狗 更新时间:2023-10-30 01:18:29 27 4
gpt4 key购买 nike

我在我的单元测试中使用了 Moq 框架。这是 UpdateApplication 测试方法:

[TestMethod]
public void UpdateApplication()
{
const string newAplpicationName = "NewApplication1";

var data =
new[]
{
new Application { Id = 1, Name = "Application1" }, new Application { Id = 2, Name = "Application2" },
new Application { Id = 3, Name = "Application3" }, new Application { Id = 4, Name = "Application4" }
}
.AsQueryable();

var mockSet = new Mock<DbSet<Application>>();
mockSet.As<IQueryable<Application>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Application>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Application>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Application>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

mockSet.Setup(m => m.AddOrUpdate(It.IsAny<Application[]>())).Callback(
(Application[] apps) =>
{
apps.FirstOrDefault(m => m.Id == 1).Name = newAplpicationName;
}).Verifiable(); // <-- Exception

var mockContext = new Mock<AppDbContext>();
mockContext.Setup(c => c.Applications).Returns(mockSet.Object);

// Act
var commandHandler = new UpdateApplicationCommandHandler(mockContext.Object);
var commandArg = new ApplicationCommandArg { Id = 1, Name = newAplpicationName };
commandHandler.Execute(new UpdateApplicationCommand(commandArg));

// Verify
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}

运行测试时出现异常:

An exception of type 'System.NotSupportedException' occurred in Moq.dll but wasnot handled in user codeAdditional information: Expression references a method that does not belong tothe mocked object: m => m.AddOrUpdate(It.IsAny())   at Moq.Mock.ThrowIfNotMember(Expression setup, MethodInfo method)   at Moq.Mock.c__DisplayClass19`1.b__18()   at Moq.PexProtector.Invoke[T](Func`1 function)   at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition)   at Moq.Mock`1.Setup(Expression`1 expression)   at UpdateApplication() in UpdateApplicationCommandTests.cs:line 39

我应该如何使用 Moq 为更新和删除操作编写单元测试?

最佳答案

这种 UpdateApplication 单元测试方法的变体对我有用,但我不确定它是否正确:

    [TestMethod]
public void UpdateApplication()
{
const string newAplpicationName = "NewApplication1";

var data =
new[]
{
new Application { Id = 1, Name = "Application1" }, new Application { Id = 2, Name = "Application2" },
new Application { Id = 3, Name = "Application3" }, new Application { Id = 4, Name = "Application4" }
}
.AsQueryable();

var mockSet = new Mock<DbSet<Application>>();
mockSet.As<IQueryable<Application>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Application>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Application>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Application>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

var mockContext = new Mock<AppDbContext>();
mockContext.Setup(m => m.Applications).Returns(mockSet.Object);


// Act
var commandHandler = new UpdateApplicationCommandHandler(mockContext.Object);
var commandArg = new ApplicationCommandArg { Id = 1, Name = newAplpicationName };
commandHandler.Execute(new UpdateApplicationCommand(commandArg));

Assert.AreEqual(newAplpicationName, data.First(m => m.Id == 1).Name);

mockContext.Verify(m => m.SaveChanges(), Times.Once());
}

但是我的 DeleteApplicationCommandTest 仍然有问题。当我运行测试时,我得到一个异常“预期对模拟的调用恰好 3 次,但是是 2 次:m => m.Applications”。这是测试方法:

    [TestMethod]
public void DeleteApplication()
{
var data =
new[]
{
new Application { Id = 1, Name = "Application1" }, new Application { Id = 2, Name = "Application2" },
new Application { Id = 3, Name = "Application3" }, new Application { Id = 4, Name = "Application4" }
}
.AsQueryable();

var mockSet = new Mock<DbSet<Application>>();
mockSet.As<IQueryable<Application>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Application>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Application>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Application>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

var mockContext = new Mock<AppDbContext>();
mockContext.Setup(m => m.Applications).Returns(mockSet.Object);

// Act
var commandHandler = new DeleteApplicationCommandHandler(mockContext.Object);
var commandArg = new ApplicationCommandArg { Id = 1 };
commandHandler.Execute(new DeleteApplicationCommand(commandArg));

// Verify
mockSet.Verify(m => m.Remove(It.IsAny<Application>()), Times.Once());
mockContext.Verify(m => m.SaveChanges(), Times.Once());
mockContext.VerifyGet(m => m.Applications, Times.Exactly(3));
}

这是我的 DeleteApplicationCommandHandler 的执行方法:

    public override void Execute(DeleteApplicationCommand command)
{
Debug.WriteLine("DeleteApplicationCommand executed");

var application = this.DbContext.Applications.FirstOrDefault(m => m.Id == command.CommandArg.Id);

if (application == null)
{
throw new Exception(string.Format("Application with id {0} was not found", command.CommandArg.Id));
}

this.DbContext.Applications.Remove(application);

this.DbContext.SaveChanges();
}

为什么 DeleteApplication 测试方法失败?

关于c# - 使用 Moq 更新、删除单元测试的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27231878/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com