如何在编写单元测试时访问方法的局部变量

时间:2015-06-26 05:47:18

标签: c# unit-testing reflection scope

鉴于以下代码:

public class Employee
{
    public void CalculateEmpSal(int empId,int salary)
    {      
        // local varibles
        int Basic; 
        int HRA;       

        // Calculate employee salary
        Basic = salry * (0.40);
        HRA = Basic * (0.50);
    }
}

是否可以为可以访问CalculateEmpSalBasic局部变量的HRA方法编写单元测试?我无法使用反射访问这些变量。还有其他方法可以从我的单元测试中访问它们吗?

3 个答案:

答案 0 :(得分:6)

你不能......而且你不应该这样做。

您应该测试由您的方法引起的副作用/状态更改,而不是低级实现细节。按照目前的情况,你的方法没有任何副作用,因此无需测试。

如果您更改它以返回有用的内容(可能是HRA),那么您可以在方法之外进行测试。

public int CalculateEmpSal(int empId,int salary)
{      
    // local varibles
    int Basic; 
    int HRA;       

    // Calculate employee salary
    Basic = salry * (0.40);
    HRA = Basic * (0.50);
    return HRA;
}

如果您只是想检查值,那么您应该使用调试器逐步执行代码..

顺便说一下,你使用浮点数,整数......你确定你想要这样做吗?

答案 1 :(得分:1)

您的代码需要进行一些重构才能正确测试和清理。我想到了几件事......

CalculateEmpSal(..)收到int empId。为什么?这不是Employee班的成员吗?:

public class Employee
{
    private readonly int id;

    public Employee(int id)
    {
         this.id = id;
    }
}

接下来的事情是你无法通过反射访问本地方法变量,既不用于测试,也不用于任何其他情况。这里不需要反思。你有两种可能性。

最好的选择是更改方法以返回具有您实际需要的值的int。我不确定HRA是什么,但这可能是你真正需要的价值。

public int CalculateEmpSal(int salary)
{      
    var basic = salary * (0.40);
    return basic * (0.50); // this was HRA once..
}

如果您需要在生产代码中的某个位置访问这两个值(basicHRA),您可以让它们成为Employee类的成员:

public class Employee
{
    // ...

    public int basicSalary {get; private set;};
    public int hraSalary {get; private set;};

    public void CalculateSalary(int salary)
    {      
        this.basicSalary = salary * (0.40);
        this.hraSalary = this.basicSalary * (0.50); 
    }

    // ...
}

但是,如果0方法从未在CalculateEmpSal的实例上调用,则会导致它们为Employee

所以我想最好在一个小包装类或其他适合你设计的东西中找到它们。例如:

public class SalaryInfo
{
    public int Salary {get; set;}
    public int Hra {get; set;}
}

public class Employee
{
    // ...

    public SalaryInfo CalculateSalary(int salary)
    {
        var retval = new SalaryInfo()
        {
            Salary = salary * (0.40),
            Hra = salary * (0.40) * (0.50) // *0.2 ...
        };

        return retval;
    }

    // ...
}

这样,您就可以在单元测试中轻松访问公共属性。

答案 2 :(得分:1)

在您的班级中,您要设置变量的值,然后在不使用的情况下将其处理掉。鉴于这一事实,如果价值观错误会有什么不同?无论如何,你没有使用它们。举个例子,我可以用它替换它,结果完全一样:

public class Employee
{
    public void CalculateEmpSal(int empId,int salary)
    {                  
    }
}

测试是关于测试副作用和/或交互。你的方法没有副作用或相互作用,因此实际上是一种低效的noop方法,无法进行测试。

你必须做的事情不是你在例子中所展示的,你知道你计算的薪水是多少。结果就是你应该测试的结果。