假设以下场景:我有一个使用PutObjectRequest
类的PhoneController
类。 Phone
是一个继承自抽象类Phone
的类,它实现了Device
接口。对于测试IPhone
我想模拟PhoneController
类,但我不知道如何使用NSubstitute来完成它,因为Phone
类继承了抽象类,并且还实现了接口。
示例代码:
Phone
Controller使用public abstract class Device
{
protected string Address { get; set; }
}
public interface IPhone
{
void MakeCall();
}
public class Phone : Device, IPhone
{
public void MakeCall()
{
throw new NotImplementedException();
}
}
public class PhoneController
{
private Phone _phone;
public PhoneController(Phone phone)
{
_phone = phone;
}
}
[TestClass]
public class PhoneControllerTests
{
[TestMethod]
public void TestMethod1()
{
// How mock Phone class?
//var mock = Substitute.For<Device, IPhone>();
//usage of mock
//var controller = new PhoneController(mock);
}
}
抽象类中的GetStatus
方法,因此Device
无法更改为_phone
类型
IPhone
答案 0 :(得分:3)
有几种方法可以做到这一点,你选择哪一种方法取决于你要测试的内容。
您可以模拟IPhone界面(就像您在注释掉的代码中所做的那样。
您可以继承Phone类(手动或使用NSubstitute的.ForPartsOf<>
)。有关此博客文章,请参阅here。
我发现如果我使用Arrange / Act / Assert方法构建我的测试,那么我想要测试的更清楚(理想情况下,你的Act部分应该有一个调用;例如:
[TestMethod]
public void TestMethod1()
{
// Arrange
var mock = Substitute.For<IPhone>();
var controller = new PhoneController(mock);
// Act
int result = controller.Method();
// Assert
Assert.Equal(result, 3);
}
编辑 - 基于更新的评论
您无法对抽象类进行单元测试,因为该类不包含(根据定义)任何代码。在您的场景中,您尝试做的就是测试具体的Phone
类。如果是这种情况,那么只需创建Phone
类的实例并对其进行测试;你不需要涉及控制器:
// Arrange
var phone = new Phone();
// Act
string result = phone.GetStatus();
// Assert
Assert.Equal("New", result);