如何模拟第三方库的工厂方法的返回类型



我正在开发一个工具,该工具使用Mono.Cicil加载程序集。我有以下Factory,它返回一个名为binary的对象,并依赖于负责使用AssemblyDefinintion.ReadAssembly方法加载程序集的接口。

我对单元测试完全陌生,我需要对GetBinary方法进行单元测试。

internal sealed class DotNetBinaryFactory : IBinaryFactory
{
private readonly IBinaryLoader binaryLoader;
public DotNetBinaryFactory(IBinaryLoader binaryLoader)
{
this.binaryLoader = binaryLoader;
}
[NotNull] public Binary GetBinary([NotNull] FilePath path)
{
var assembly = binaryLoader.LoadBinary(path);
return BinaryUtils.GetBinary(assembly);
}
}

以下是IBinaryLoader依赖性实现

internal interface IBinaryLoader
{
AssemblyDefinition LoadBinary(FilePath path);
}
internal sealed class DotnetBinaryLoader : IBinaryLoader
{
public AssemblyDefinition LoadBinary([NotNull] FilePath path)
{
try
{
return AssemblyDefinition.ReadAssembly(path.Path);
}                
catch (Exception)
{
Console.WriteLine("Exception in loading Assembly From : " + path.Path);
throw;
}
}
}

因此,为了对GetBinary方法进行单元测试,我需要模拟IBinaryLoader并设置LoadBinary方法以返回一个伪AssemblyDefinition对象,但我无法创建一个。

以下是我尝试的

[Test]
public void GetDotnetBinary_AssemblyDefinitionInput_ReturnCorrectDotnetFrameworkBianry()
{
var path = FilePath.GetRandom();
var mockedAssemblyDef = new Mock<AssemblyDefinition>();
var binaryLoader = new Mock<IBinaryLoader>();
binaryLoader.Setup(m => m.LoadBinary(path)).Returns(mockedAssemblyDef.Object);
}

您需要创建服务的mock,而不是数据的mock。在您的情况下,AssemblyDefinition是数据,也是sealed。Mock并不适用于具体的数据类。你对";服务";binaryLoader看起来不错。

相反,您需要做的是以另一种方式创建您的伪AssemblyDefinition,并返回它。我不熟悉Mono.Cecil,但看起来有一个静态Create((方法可以使用。一旦你得到了你需要的实例,剩下的测试就应该到位了。

你最终会得到类似的东西

[Test]
public void GetDotnetBinary_AssemblyDefinitionInput_ReturnCorrectDotnetFrameworkBianry()
{
// arrange
var path = FilePath.GetRandom();
var assemblyDef = AssemblyDefinition.Create(...); // or however your create a real one
var binaryLoader = new Mock<IBinaryLoader>();
binaryLoader.Setup(m => m.LoadBinary(path)).Returns(assemblyDef);
var factory = new DotNetBinaryFactory(binaryLoader);
// act
var result = factory.GetBinary(path);
// assert
// your assertions here...
}

我也看到你的类型是内在的。假设您的测试在不同的程序集中,则必须使该程序集中的内部可见。这是通过在源程序集中放置[InteralsVisibleTo]特性来完成的。

相关内容

  • 没有找到相关文章

最新更新