我正在开发一个工具,该工具使用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]特性来完成的。