如何使用硬编码参数对方法进行单元测试?

时间:2021-04-01 12:54:58

标签: c# xunit

我有一个带有方法的类。此方法检查程序集/命名空间并读取该命名空间中名为 ProductModel 的所有类的内容:

    public static IEnumerable<ProductModel?> GetProductModels()
    {
        var typesList = Assembly.GetExecutingAssembly()
            .GetTypes().Where(x =>
                x.Name.Contains("ProductModel") && // This is the name of the classes
                x.FullName!.Contains("MyProject.Domain.ProductTypes")) // This is the namespace of the project
            .ToList();

        var ProductModelLists = typesList.Select(x =>
       {
           return GetProductModelMethod(x);
       });

        if (ProductModelLists == null)
        {
            throw new ArgumentException("No ProductModel Found");
        }
        else{
          return ProductModelLists;
        }   
    }

此类和方法与 ProductTypes/ProductModels - MyProject.Domain.ProductTypes 位于同一项目和命名空间中。

我想使用 XUnit 来测试 2 个场景 - 一个有 ProductModels 和一个没有并且抛出 Argument 异常的场景。

由于值是在方法中硬编码的,对我来说这几乎是不可能的。有没有人对如何做类似的事情有任何提示?

1 个答案:

答案 0 :(得分:2)

与实现细节的紧密耦合使得隔离该代码变得困难。考虑重构以使用抽象和显式依赖原则,使代码更加可靠。

鉴于被测主题成员是一个 static 函数,我假设这是在某个静态实用程序类中。核心功能仍然可以重构为它自己的功能,允许可以操纵的输入。

public static IEnumerable<ProductModel?> GetProductModelsCore(IEnumerable<Type> types) {
    var typesList = types.Where(x =>
            x.Name.Contains("ProductModel") && // This is the name of the classes
            x.FullName!.Contains("MyProject.Domain.ProductTypes")) // This is the namespace of the project
        .ToList();

    var ProductModelLists = typesList.Select(x => {
       return GetProductModelMethod(x);
    });

    if (ProductModelLists == null) {
        throw new ArgumentException("No ProductModel Found");
    } else {
      return ProductModelLists;
    }   
}

并从主函数调用

public static IEnumerable<ProductModel?> GetProductModels() =>
    GetProductModelsCore(Assembly.GetExecutingAssembly().GetTypes());

可以使用满足所需场景的假类型单独测试核心功能。

同样,理想情况下,这应该转移到具有抽象的服务,这些抽象允许更可靠的代码库,从而有助于更好的维护,但基于当前超出本答案范围的原始代码。