从抽象类继承并实现接口的Mock类

时间:2018-05-10 15:39:33

标签: c# unit-testing mocking nsubstitute

假设以下场景:我有一个使用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

1 个答案:

答案 0 :(得分:3)

有几种方法可以做到这一点,你选择哪一种方法取决于你要测试的内容。

  1. 您可以模拟IPhone界面(就像您在注释掉的代码中所做的那样。

  2. 您可以继承Phone类(手动或使用NSubstitute的.ForPartsOf<>)。有关此博客文章,请参阅here

  3. 我发现如果我使用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);