我想用C#(使用NUnit)编写一些单元测试,但是我不确定如何继续。
所以我有一个类,它提供一个具有四个属性的用户模型DataModel。我在ExcelInit构造函数中发送此模型。
DataModel dm = new DataModel();
dm.PopulateDataModel(holder);
ExcelInit d1 = new ExcelInit(dm);
d1.BeginProcess();
,然后在BeginProcess中启动我的实际方法。
public class ExcelInit
{
public DataModel _model { get; set; }
public ExcelInit(DataModel model)
{
_model = model;
}
public void BeginProcess()
{
DataReader dr = new DataReader();
CellLocation cl = new CellLocation();
//Gets the corresponding cellAddress for the cell that contains "2x5" from our hidden config-sheet
var correspondingCellsAddress = cl.FindCorrespondingCellAddress(_model.boxSize);
//returns the range that we need to copy i.e. the whole range of the box ala B3:AG13
var srcRange = dr.GetRangeForSourceDestination(correspondingCellsAddress);
//Last row of sheet 6 (the sheet we populate) with input-boxes
var lastRow = dr.FindLastRowByName("Your_Data_Sheet") + 3;
//gets the cell we'll copy our range to
var destRange = "B" + lastRow.ToString();
DataHandler dh = new DataHandler();
dh.CopyBox(srcRange, destRange, _model);
}
但是正如您所看到的,我在BeginProcess中创建了很多类,我的老师告诉我,我不能这样做(我需要使用DI才能进行测试)。但是我的问题是,当我需要在方法中使用这么多的类时,如何使用DI?还是我的方法不对,我不应该依赖太多不同的事物吗?
答案 0 :(得分:1)
DI的目的不是避免创建实例。甚至DI容器也必须以某种方式创建依赖项的实例,例如通过反射。
DI大约在位置处创建那些实例。话虽如此,您不应该让被测系统(SuT,在您的情况下为类ExcelInit
)创建自己的依赖项,而只是将它们注入到系统中,例如通过使用构造函数注入或仅将参数设置为您的方法:
public void BeginProcess(DataReader dr, CellLocation cl, DataHandler dh)
{
//Gets the corresponding cellAddress for the cell that contains "2x5" from our hidden config-sheet
var correspondingCellsAddress = cl.FindCorrespondingCellAddress(_model.boxSize);
//returns the range that we need to copy i.e. the whole range of the box ala B3:AG13
var srcRange = dr.GetRangeForSourceDestination(correspondingCellsAddress);
//Last row of sheet 6 (the sheet we populate) with input-boxes
var lastRow = dr.FindLastRowByName("Your_Data_Sheet") + 3;
//gets the cell we'll copy our range to
var destRange = "B" + lastRow.ToString();
dh.CopyBox(srcRange, destRange, _model);
}
现在在您的测试中,您已经有了:
var target = new ExcelInit();
target.BeginProcess(new DataReader(), new CellLocation(), new DataHandler());
当然,这将执行完全相同的指令。但是,您现在也可以这样做:
var target = new ExcelInit();
target.BeginProcess(new SomeSpecificDataReader(), new CellLocation(), new DataHandler());
当您只是将阅读器注入而不是在SuT中创建阅读器时,实际的SuT根本就不会改变。因此,实际上您的被测系统并不依赖于特定的文件,而是依赖于数据。此数据的存储位置与您的BeginProcess
方法无关。例如,您可以提供另一个excel文件(假设您的系统使用excel文件),一个xml文件或什至是一些内存中的数据存储。
答案 1 :(得分:0)
您的老师似乎使您感到困惑,并且可能使自己困惑。
如果依赖项由您控制,他的建议将起作用。那不是你的情况。您正在直接使用Excel的API,并且使用new注入您正在创建的类不会帮助您进行可测试性。如果您要遵循老师的建议,则必须为整个Excel的API创建测试倍数,我认为这是不可能的,因为该API并非为可测试性而设计。
遵循老师建议的一种方法是创建自己的包装Excel的API。考虑到可测试性,可以做到这一点。但是查看您的代码,我觉得这只会将问题向下推一层。您将使解决方案复杂化,而无需对真正重要的代码进行自动测试。
我建议您请老师给他举例说明他的意思。注入这些类将如何通过编写实际测试来提高代码的可测试性。我敢肯定,如果在您的方案中创建更多可测试的代码实际上没有帮助的话,他也会实现他的建议。