如何为调用其他服务的方法编写单元测试
How to write a unit test for a method which calls other services
我有一个调用另一个服务的方法,但是在调用内部服务之前有一些数据操作。请看下面
public async Task<myObject> Save(string server,string username, myObject element)
{
string temp = element.Class + "_" + element.Description + "_" + username;
var saveData = new string[] { element.Name, temp};
var response = await datService.save(server, saveData);
var result = response.TomyObject(); // this is the extension method to convert response to myObject.
return result ;
}
单元测试的最佳方法是什么?
我试过跟随但只是想确保我正在做 "correct" 方式。
public async Task Save_Success()
{
//ARRANGE
var element = new myObject
{
Name = "Test",
Description = "Test Save",
Class = "test class"
};
string temp = element.Class+ "_" + element.Description + "_" + username;
var saveData = new string[] { element.Name, temp};
var response = new anotherObject
{
Name= "Test",
MyArray = new objArray
{
P0 = saveData[0],
P1 = saveData[1]
},
Error = ""
};
var datService = new Mock<IDataService>();
datService.Setup(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()).Returns(Task.FromResult(response));
var myClass = new MyClass(datService.Object);
//ACT
var result = await myClass.Save("testServer","testUser", element);
// ASSERT
Assert.AreEqual(response.MyArray.P0, result.Class);
}
这里是扩展方法
public static myObject TomyObject(this anotherObject response)
{
var entity = new myObject();
entity.Name = response.Name;
if(response.MyArray!= null && response.MyArray.P1 != "")
{
string[] details = response.MyArray.P1.Split('_');
entity.Class = details[0];
entity.Description = details[1];
}
return entity;
}
以下是测试扩展方法的方法:
anotherObject response = new anotherObject
{
Name = "TestName",
MyArray = new objArray
{
P1 = "Val1_Val2"
}
};
var result = response.TomyObject();
Assert.Equal("TestName", result.Name);
Assert.Equal("Val1", result.Class);
Assert.Equal("Val2", result.Description);
关键是让你的单元测试只测试一个工作单元。如果您想测试您的扩展方法,请为它编写一个测试 隔离 。一旦你开始包括多个工作单元(即 IDataService
),你实际上是在测试一个系统,它变成了一个集成测试。
更新:
在你的 Save_Success
测试的这一行:
// ASSERT
Assert.AreEqual(response.MyArray.P0, result.Class);
你实际上是在测试一些不属于 Save
方法责任的东西(设置 Class
属性 实际上是你的 TomyObject
的责任,这可能单独测试)。
要验证 Save
方法是否正常工作,您可以这样做:
// ASSERT
datService.Verify(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()), Times.Once);
这样,您只是在测试 Save
方法是否正在执行它明确负责执行的操作。
我有一个调用另一个服务的方法,但是在调用内部服务之前有一些数据操作。请看下面
public async Task<myObject> Save(string server,string username, myObject element)
{
string temp = element.Class + "_" + element.Description + "_" + username;
var saveData = new string[] { element.Name, temp};
var response = await datService.save(server, saveData);
var result = response.TomyObject(); // this is the extension method to convert response to myObject.
return result ;
}
单元测试的最佳方法是什么? 我试过跟随但只是想确保我正在做 "correct" 方式。
public async Task Save_Success()
{
//ARRANGE
var element = new myObject
{
Name = "Test",
Description = "Test Save",
Class = "test class"
};
string temp = element.Class+ "_" + element.Description + "_" + username;
var saveData = new string[] { element.Name, temp};
var response = new anotherObject
{
Name= "Test",
MyArray = new objArray
{
P0 = saveData[0],
P1 = saveData[1]
},
Error = ""
};
var datService = new Mock<IDataService>();
datService.Setup(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()).Returns(Task.FromResult(response));
var myClass = new MyClass(datService.Object);
//ACT
var result = await myClass.Save("testServer","testUser", element);
// ASSERT
Assert.AreEqual(response.MyArray.P0, result.Class);
}
这里是扩展方法
public static myObject TomyObject(this anotherObject response)
{
var entity = new myObject();
entity.Name = response.Name;
if(response.MyArray!= null && response.MyArray.P1 != "")
{
string[] details = response.MyArray.P1.Split('_');
entity.Class = details[0];
entity.Description = details[1];
}
return entity;
}
以下是测试扩展方法的方法:
anotherObject response = new anotherObject
{
Name = "TestName",
MyArray = new objArray
{
P1 = "Val1_Val2"
}
};
var result = response.TomyObject();
Assert.Equal("TestName", result.Name);
Assert.Equal("Val1", result.Class);
Assert.Equal("Val2", result.Description);
关键是让你的单元测试只测试一个工作单元。如果您想测试您的扩展方法,请为它编写一个测试 隔离 。一旦你开始包括多个工作单元(即 IDataService
),你实际上是在测试一个系统,它变成了一个集成测试。
更新:
在你的 Save_Success
测试的这一行:
// ASSERT
Assert.AreEqual(response.MyArray.P0, result.Class);
你实际上是在测试一些不属于 Save
方法责任的东西(设置 Class
属性 实际上是你的 TomyObject
的责任,这可能单独测试)。
要验证 Save
方法是否正常工作,您可以这样做:
// ASSERT
datService.Verify(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()), Times.Once);
这样,您只是在测试 Save
方法是否正在执行它明确负责执行的操作。