C# 创建具有依赖项的具体类的Moq

C# 创建具有依赖项的具体类的Moq,c#,.net,unit-testing,moq,C#,.net,Unit Testing,Moq,我有一个具体的类CalculatorService,我想测试CalculateBuyOrder方法。CalculatorService通过构造函数参数注入了多个依赖项,CalculateBuyOrder在同一服务上调用另一个方法 我需要一个模仿那个班的人 可以在没有无参数构造函数的情况下创建,即自动模拟依赖关系树。 默认情况下,所有方法都是mock stubbed的,可以选择重写并调用一个或多个方法的实际实现。 这似乎是一个如此明显和基本的用例,但我自己似乎既无法理解它,也无法找到解释它的文档。

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

我需要一个模仿那个班的人

可以在没有无参数构造函数的情况下创建,即自动模拟依赖关系树。 默认情况下,所有方法都是mock stubbed的,可以选择重写并调用一个或多个方法的实际实现。 这似乎是一个如此明显和基本的用例,但我自己似乎既无法理解它,也无法找到解释它的文档。我得到的最远的结果是实现1,但是2。我被难住了

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不再需要无参数构造函数了?这里面到处都是代码味道。