I have the following interface
public interface ICommand<TResult, TModel>
{
Task<TResult> DoWorkAsync(TModel model);
}
Which is implemented by one or more such Command classes:
public class MyCommand1 : ICommand<Response, Model>()
{
public async Task<Response> DoWorkAsync(Model model) {
// do something
}
}
public class MyCommand2 : ICommand<Response, Model>()
{
public async Task<Response> DoWorkAsync(Model model) {
// do something else
}
}
The Respose and Model classes are as follows:
public class Response
{
public bool IsSuccessful {get;set;}
}
public class Model
{
public Guid Id {get;set;}
public string Name {get;set;}
}
Then I have an orchestrator class that has a dependency on an IEnumerable of IEnumerable<ICommand<Response, Model>>
public class MyOrchestrator
{
private readonly IEnumerable<ICommand<Response, Model>> _commands;
public MyOrchestrator(IEnumerable<ICommand<Response, Model>> commands)
{
_commands = commands;
}
public async Task ExecuteAsync(Model model)
{
myCommand1_Response = await _commands
.OfType<MyCommand1>()
.First()
.DoWorkAsync(model);
myCommand2_Response = await _commands
.OfType<MyCommand2>()
.First()
.DoWorkAsync(model);
// other operations
}
}
Now in my test I'm trying to mock the MyOrchestrator class's dependency IEnumerable<ICommand<Response, Model>>
for each of the MyCommand types. How can I achieve this?
CodePudding user response:
The problem is that MyCommand2 and MyCommand1 are concrete classes. You'll either need to make them be IMyCommand1 and IMyCommand2 or make DoWorkAsync
virtual.
CodePudding user response:
I think you could simplify your orchestator which would make mocking trivial.
public class MyOrchestrator
{
...
public MyOrchestrator(ICommand<Response, Model> command1, ICommand<Response, Model> command2)
{
this.command1 = command1 ?? throw...;
this.command2 = command2 ?? throw...;
}
public async Task ExecuteAsync(Model model)
{
myCommand1_Response = await command1.DoWorkAsync(model);
myCommand2_Response = await command1.DoWorkAsync(model);
// other operations
}
}
Now mocking this is nothing special.
var mockCommand1 = new Mock<ICommand<Response, Model>>(MockBehaviour.Strict);
...
var tested = new MyOrchestrator(command1: mockCommand1.Object, ...);