Рассмотрим реализацию команды SendCommand, которая разрешает явно зависимость с помощью IoC:
interface ICommandReceiver
{
void Receive(ICommand cmd);
}
class SendCommand(ICommand sendingCommand) : ICommand
{
public void Execute()
{
var receiver = Ioc.Resolve<ICommandReceiver>("Game.CommandsReceiver");
receiver.Receive(cmd);
}
}
Напишем тест, который проверяет, что при выполнении команды SendCommand команда будет передана получателю:
class SendCommandTests
{
public SendCommandTests()
{
new InitCommand().Execute();
var iocScope = Ioc.Resolve<object>("IoC.Scope.Create");
Ioc.Resolve<ICommand>("IoC.Scope.Current.Set", iocScope).Execute();
}
[Fact]
void SendCommand_Should_Send_A_Command_To_The_Command_Receiver()
{
var commandMock = new Mock<ICommand>();
var cmd = commandMock.Object;
var commandReceiverMock = new Mock<ICommandReceiver>();
var receiver = commandReceiverMock.Object;
Ioc.Resolve<ICommand>(
"IoC.Register",
"Game.CommandReceiver",
(object[] args => receiver)
).Execute();
new SendCommand(cmd).Execute();
commandReceiveMock.Verify(r => r.Receive(cmd), Times.Once());
}
}
Если использовать инъекцию зависимостей через конструктор, то можно отказаться от явного вызова IoC при реализации SendCommand:
interface ICommandReceiver
{
void Receive(ICommand cmd);
}
class SendCommand(ICommand sendingCommand, ICommandReceiver receiver) : ICommand
{
public void Execute()
{
receiver.Receive(cmd);
}
}
Тогда и в тестах можно отказаться от использования IoC в тестах:
class SendCommandTests
{
[Fact]
void SendCommand_Should_Send_A_Command_To_The_Command_Receiver()
{
var commandMock = new Mock<ICommand>();
var cmd = commandMock.Object;
var commandReceiverMock = new Mock<ICommandReceiver>();
var receiver = commandReceiverMock.Object;
new SendCommand(cmd, receiver).Execute();
commandReceiveMock.Verify(r => r.Receive(cmd), Times.Once());
}
}