Reputation: 641
I have a concrete class CalculatorService
of which I want to test CalculateBuyOrder()
method. CalculatorService
has several dependencies injected through constructor parameters and CalculateBuyOrder()
calls another method on the same service.
I need a mock of the class that
It seems such an obvious and basic use case, but I can't seem to neither figure it out myself nor find the documentation that explains it. The furthest I've gotten is using AutoMocker for achieving 1., but 2. has me stumped.
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()
{
// ...
}
}
}
Upvotes: 0
Views: 1929
Reputation: 136
As some of the comments have said you should place interfaces in your constructor as for an example pseudo code:
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
}
}
notice all the parameters in the constructor are interfaces. and then your test method would look a little like this
[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);
}
For more information just go to this link Moq Github.
Now for the second part of your question, mocking a method within the same class. This defeats the purpose of mocking, as mocking is to "fake" dependencies. So either restructure the code so you can mock it properly, or make sure any methods it calls are mocked in a way they'll give a reliable output that you can use.
Upvotes: 1