将接口抽象为具有扩展方法的类

时间:2016-08-23 14:13:27

标签: c# visual-studio unit-testing nunit

如果我在该类中使用扩展方法,如何使用其接口替换具体类以进行单元测试?

我有一个方法:

[HttpGet]
[Route("/yoyo/{yoyoId:int}/accounts")]
public ResponseYoyoEnvelope GetAccountsByYoyoId([FromBody] RequestYoyoEnvelope requestYoyoEnvelope, int yoyoId)
{
    var responseYoyoEnvelope = requestYoyoEnvelope.ToResponseYoyoEnvelope();

    // get our list of accounts
    // responseEnvelope.Data = //list of accounts
    return responseYoyoEnvelope;
}

我想替换:

RequestYoyoEnvelope requestYoyoEnvelope

带抽象:

IRequestYoyoEnvelope requestYoyoEnvelope

但是,ToResponseYoyoEnvelope是一种扩展方法。

如果我在该类中使用扩展方法,如何使用其接口替换具体类以进行单元测试?

2 个答案:

答案 0 :(得分:4)

您可以针对接口而不是具体类编写扩展方法:

public static class Class2
{
    public static void Extension(this ITestInterface test)
    {
        Console.Out.WriteLine("This is allowed");
    }
}

然后你可以这样做:

// "Test" is some class that implements the ITestInterface interface
ITestInterface useExtensionMethod = new Test();
useExtensionMethod.Extension();

另请注意,即使useExtensionMethod未明确指出ITestInterface类型,这仍然有效:

Test useExtensionMethod = new Test();
useExtensionMethod.Extension();

controversy关于这是否代表装饰者模式,但至少要记住,扩展方法并不是界面本身的一部分 - it's still a static method& #34;引擎盖下,"它只是编译器允许您像处理实例方法一样方便地处理它。

答案 1 :(得分:2)

假设

public class RequestYoyoEnvelope : IRequestYoyoEnvelope { ... }

您的扩展方法需要定位接口

public static ResponseYoyoEnvelope ToResponseYoyoEnvelope(this IRequestYoyoEnvelope target) { ... }

保持操作不变,因为模型绑定器会出现绑定接口的问题。

在您的单元测试中,您传递了RequestYoyoEnvelope的具体实现,并且应该能够测试更新的扩展方法。

从您的示例中,您不需要接口来测试该方法是否为测试方法。只需新建一个模型实例,并在单元测试期间将其传递给方法。

[TestMethod]
public void GetAccountsByYoyoIdTest() {
    //Arrange
    var controller = new YoyoController();
    var yoyoId = 123456;
    var model = new RequestYoyoEnvelope {
        //you populate properties for test
    };
    //Act
    var result = controller.GetAccountsByYoyoId(model, yoyoId);

    //Assert
    //...do your assertions.
}