gpt4 book ai didi

c# - 使用最小起订量测试存储库

转载 作者:太空狗 更新时间:2023-10-30 00:25:03 25 4
gpt4 key购买 nike

我正在尝试使用 MOQ 来测试存储库以模拟存储库的行为。我是最小起订量的新手,所以请多多包涵。

给定以下方法:

public static SubmissionVersion DeleteNote(IRepository repository, SubmissionVersion version, Guid noteId)
{
Note note = repository.GetById<Note>(noteId);
version.Notes.Remove(note);
repository.Save(version);
repository.Delete(note);
return repository.GetById<SubmissionVersion>(version.Id);
}

这个测试看起来还行吗?

[Fact]
public void DeleteNoteV2()
{
// Arrange
var note = new Note{ Id = Guid.NewGuid()};

var subVersion = new Mock<SubmissionVersion>();
subVersion.Setup(x => x.Notes.Remove(note));

var repo = new Mock<IRepository>();
repo.Setup(x => x.GetById<Note>(note.Id)).Returns(note);
repo.Setup(x => x.GetById<SubmissionVersion>(It.IsAny<Guid?>())).Returns(subVersion.Object);

// Act
SubmissionVersion.DeleteNote(repo.Object, subVersion.Object, note.Id.Value);

// Assert
repo.Verify(x => x.GetById<Note>(note.Id), Times.Once());
repo.Verify(x => x.Save(subVersion.Object), Times.Once());
repo.Verify(x => x.Delete(note), Times.Once());

subVersion.Verify(x => x.Notes.Remove(It.IsAny<Note>()), Times.Once());
}

最佳答案

你的方法很好,但我会调整一些东西。我对您的测试和模拟组件做了一些更改,您可以在下面看到。

单元测试

您在单元测试中测试的方法(见下文)与您在问题中定义的方法并不完全匹配。

单元测试方法调用:

SubmissionVersion.DeleteNote(repo.Object, subVersion.Object, note.Id.Value);

待测方法:

public static SubmissionVersion DeleteNote
(IRepository repository, SubmissionVersion version, Guid noteId)

我假设上述方法是另一个类的一部分,我称它为 NotesHelper - 不是存储库调用的理想名称,但它只是为了让编译工作。

我会亲自将您的单元测试分成 2 个独立的单元测试。一个是验证是否调用了所需的方法,另一个是验证笔记是否已从集合中删除。

此外,我没有创建模拟的 SubmissionVersion,而是创建了一个 fakeSubmissionVersion。这是因为 SubmissionVersion 中的例程可能不可模拟。您还可以进行基于状态的测试(首选)以确保 version.Notes.Remove(note);已被调用。

[Fact]
public void DeleteNote_Deletion_VerifyExpectedMethodsInvokecOnlyOnce()
{
// Arrange
var note = new Note { Id = Guid.NewGuid() };
var fakeSubmissionVersion = new SubmissionVersion() { Notes = new List<Note>() };
var repo = new Mock<IRepository>();
repo.Setup(x => x.GetById<Note>(It.IsAny<Guid>())).Returns(note);

// Act
NotesHelper.DeleteNote(repo.Object, fakeSubmissionVersion, note.Id.Value);

// Assert
repo.Verify(x => x.GetById<Note>(note.Id), Times.Once());
repo.Verify(x => x.Save(fakeSubmissionVersion), Times.Once());
repo.Verify(x => x.Delete(note), Times.Once());
}

可以通过在自己的测试中定义每个验证来进一步改进上述测试。

[Fact]
public void DeleteNote_Deletion_VerifyDeleteMethodCalledOnlyOnce()

这样一来,如果某个测试失败了,我们就可以确切地知道哪个方法没有按照预期被调用。有时,如上所述进行多次验证可能会出现问题。例如,如果没有调用 Save 方法,您永远不会知道是否调用了 Delete 方法。这是因为在没有调用Save方法时抛出了异常,测试执行已经终止。

这会导致多次测试,但它们更具可读性和可维护性。当然,您可以将公共(public)代码重构为工厂或辅助方法。

[Fact]
public void DeleteNote_RemoveNotes_ReturnsExpectedNotes()
{
// Arrange
var note = new Note { Id = Guid.NewGuid() };
var fakeSubmissionVersion = new SubmissionVersion() { Notes = new List<Note>() { note } };
var repo = new Mock<IRepository>();
repo.Setup(x => x.GetById<Note>(It.IsAny<Guid>())).Returns(note);

// Act
NotesHelper.DeleteNote(repo.Object, fakeSubmissionVersion, note.Id.Value);

// Assert
Assert.AreEqual(0, fakeSubmissionVersion.Notes.Count);
}

附加说明:同时提供描述性单元测试方法名称可提高单元测试的可读性。

关于c# - 使用最小起订量测试存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19578551/

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