繁体   English   中英

创建具有依赖关系的具体类的最小起订量

[英]Create a Moq of a concrete class with dependencies

我有一个具体的类CalculatorService ,要测试CalculateBuyOrder()方法。 CalculatorService通过构造函数参数注入了几个依赖项,并且CalculateBuyOrder()在同一服务上调用另一个方法。

我需要一个班级的模拟

  1. 可以在没有无参数构造函数的情况下创建(即自动模拟依赖关系树)。
  2. 默认情况下是否对所有方法都进行了模拟(存根),并且可以选择重写(或重写)一个(或多个)方法的实际实现。

这似乎是一个显而易见的基本用例,但是我似乎既无法自己弄清它,也无法找到解释它的文档。 我得到的最远的结果是使用AutoMocker实现了1.,但是让我感到困惑

public class CalculatorService
    : ICalculatorService
{
    private readonly IMainDbContext _db;
    private readonly TradeConfig _tradeConfig;
    private readonly MainConfig _config;
    private readonly StateConfig _state;
    private readonly ICurrencyService _currencyService;
    private readonly IExchangeClientService _client;


    // Parameters need to be mocked
    public CalculatorService(MainDbContext db, TradeConfig tradeConfig, MainConfig config, StateConfig state, ICurrencyService currencyService, IExchangeClientService client)
    {
        this._db = db;
        this._tradeConfig = tradeConfig;
        this._config = config;
        this._state = state;
        this._currencyService = currencyService;
        this._client = client;
    }

    // This needs to be tested
    public async Task<OrderDto> CalculateBuyOrder(
        String coin,
        CoinPriceDto currentPrice,
        Decimal owned,
        IDictionary<TradeDirection, OrderDto> lastOrders,
        OrderDto existingOrder = null,
        TradeConfig.TradeCurrencyConfig tradingTarget = null,
        Decimal? invested = null)
    {

        // ...
        this.GetInvested();
        // ...
    }

    // This needs to be mocked
    public virtual IDictionary<String, Decimal> GetInvested()
    {
        // ...
    }
}

}

正如一些评论所说,您应该将接口放置在构造函数中,例如一个伪代码示例:

public class Foo : IFoo
{
    IBoo boo;
    IGoo goo;
    public Foo(IBoo boo, IGoo goo)
    {
        this.boo = boo;
        this.goo = goo;
    }
    public int MethodToTest(int num1,int num2)
    {
        //some code
        /*..*/ = boo.Method(num1,num2);
        //more code and return
    }
}

注意构造函数中的所有参数都是接口。 然后您的测试方法将看起来像这样

[TestMethod]
public void TestMethod()
{
    //setting up test
    var boo = new Mock<IBoo>();
    var goo = new Mock<IGoo>();
    var foo = new Foo(boo.object,goo.object);
    boo.Setup(x=>x.Method(1,2)).Returns(10);
    //running test
    var result = foo.MethodToTest(1,2);
    //verify the test
    Assert.AreEqual(12,result);
}

有关更多信息,请转到此链接Moq Github

现在,对于问题的第二部分,在同一类中模拟一个方法。 由于模拟是“伪造”依赖关系,因此这无法实现模拟的目的。 因此,要么重组代码,以便您可以正确地模拟它,要么确保以某种方式模拟了它所调用的任何方法,它们将提供可使用的可靠输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM