gpt4 book ai didi

c# - 单元测试模拟框架是否会以您的编程方式强制您?

转载 作者:行者123 更新时间:2023-11-30 14:25:46 25 4
gpt4 key购买 nike

我正在使用 Moq 框架设置单元测试。

我有一个这样描述类的接口(interface):

public interface ISourceFileLocation : IFileLocation, IDisposable
{
bool RemoveAfterTransfer { get; set; }
void RemoveSource();
//.....
}

为了确保调用 RemoveSource-Method,我实现了一个基类,其中在 dispose 方法中调用了 remove。

public abstract class SourceFileBase : ISourceFileLocation
{
//......

public bool RemoveAfterTransfer { get; set; }

public void RemoveSource()
{
if (File.Exists(Uri.AbsolutePath))
{
File.Delete(Uri.AbsolutePath);
}
}

public void Dispose()
{
if (this.RemoveAfterTransfer)
this.RemoveSource();
}
}

当模拟 ISourceFileLocation 时没有默认实现,所以为了测试我想在具体类应该继承的基类上实现测试。

当模拟基类时,我的测试期望 RemoveSource-Method 是虚拟的,这打破了我确保调用该方法的想法!!

这是缺少框架,是否有更好的框架或方法来测试它,或者这是我的代码的问题,我应该重新考虑我的设计吗?

亲切的问候。

测试方法:

    [TestCategory("Source")]
[TestMethod]
public void CheckIfRemoveSourceMethodIsCalled()
{
//ARRANGE
var mockSourceLocation = new Mock<SourceFileBase>();
mockSourceLocation.Object.RemoveAfterTransfer = true;
mockSourceLocation.Setup(x => x.RemoveSource());
//ACT
mockSourceLocation.Object.Dispose();
/ASSERT
mockSourceLocation.VerifyAll();
}

[TestCategory("Source")]
[TestMethod]
public void CheckIfRemoveSourceMethodIsNotCalled()
{
//ARRANGE
var mockSourceLocation = new Mock<SourceFileBase>();
mockSourceLocation.Object.RemoveAfterTransfer = false;
//ACT
mockSourceLocation.Object.Dispose();
//ASSERT
mockSourceLocation.Verify(x=>x.RemoveSource(), Times.Never);
}

最佳答案

我认为您可能在这个示例中滥用了 Moq,因为您正在为您的被测系统 (SUT) 使用相同的模拟对象,并执行您的行为验证。您的测试实质上是检查 SourceFileBase 是否调用自身。通常,您会使用 Moq 来验证对 SUT 的依赖项的调用。

SourceFileBase 中的代码不是单元测试友好的,因为它直接在 File 类上使用静态方法。为了使其可单元测试,您需要以某种方式对其进行抽象(例如,参见 this question )。

public abstract class SourceFileBase : ISourceFileLocation
{
private readonly IFileSystem _fileSystem;

public SourceFileBase(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}

...

public void RemoveSource()
{
_fileSystem.DeleteFile(Uri.AbsolutePath);
}

public void Dispose()
{
RemoveSource();
}
}

这样做可以让您测试 Dispose()RemoveSource() 是否都删除了文件。

// Arrange
var mockFileSystem = new Mock<IFileSystem>();
var sut = new Mock<SourceFileBase>(mockFileSystem.Object);
sut.RemoveAfterTransfer = true;
sut.Uri = myTestUri;

// Act
sut.Dispose();

// Assert
mockFileSystem.Verify(f => f.DeleteFile(myTestUri.AbsolutePath));

关于c# - 单元测试模拟框架是否会以您的编程方式强制您?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37271844/

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