mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
AppTests
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
using Govor.ConsoleClient.Services.Interfaces;
|
||||
using Moq;
|
||||
|
||||
namespace Govor.ConsoleClient.Tests;
|
||||
|
||||
[TestFixture]
|
||||
public class AppTests
|
||||
{
|
||||
private Mock<IInputPipeline> _inputPipelineMock = null!;
|
||||
private Mock<ILogger> _loggerMock = null!;
|
||||
private App _app = null!;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_inputPipelineMock = new Mock<IInputPipeline>();
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_inputPipelineMock.Setup(f => f.ProcessInputAsync(It.IsAny<string>())).Returns(Task.CompletedTask);
|
||||
|
||||
_app = new App(_inputPipelineMock.Object, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RunAsync_PrintsTitleOnce()
|
||||
{
|
||||
using var sr = new StringReader("exit");
|
||||
Console.SetIn(sr);
|
||||
|
||||
await _app.RunAsync();
|
||||
|
||||
_loggerMock.Verify(l => l.Title(It.Is<string>(s => s.Contains("Говор"))), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RunAsync_CallsInputPipeline_ForEachInput()
|
||||
{
|
||||
var inputText = "hello\n/command\nexit";
|
||||
using var sr = new StringReader(inputText);
|
||||
Console.SetIn(sr);
|
||||
|
||||
await _app.RunAsync();
|
||||
|
||||
_inputPipelineMock.Verify(p => p.ProcessInputAsync("hello"), Times.Once);
|
||||
_inputPipelineMock.Verify(p => p.ProcessInputAsync("/command"), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RunAsync_StopsOnExit()
|
||||
{
|
||||
using var sr = new StringReader("exit");
|
||||
Console.SetIn(sr);
|
||||
|
||||
await _app.RunAsync();
|
||||
|
||||
// Убедимся, что ProcessInputAsync вообще не вызывался
|
||||
_inputPipelineMock.Verify(p => p.ProcessInputAsync(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="NUnit" Version="4.3.2" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="NUnit.Framework" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Govor.ConsoleClient\Govor.ConsoleClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,124 @@
|
||||
using Govor.ConsoleClient.Commands;
|
||||
using Govor.ConsoleClient.Services.Implementations;
|
||||
using Govor.ConsoleClient.Services.Interfaces;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Govor.ConsoleClient.Tests.Services.Implementations;
|
||||
|
||||
[TestFixture]
|
||||
public class InputPipelineTests
|
||||
{
|
||||
private Mock<ICommandDispatcher> _commandDispatcherMock = null!;
|
||||
private Mock<ILogger> _loggerMock = null!;
|
||||
private InputPipeline _inputPipeline = null!;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_commandDispatcherMock = new Mock<ICommandDispatcher>();
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_inputPipeline = new InputPipeline(_commandDispatcherMock.Object, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_EmptyOrWhitespaceInput_DoesNothing()
|
||||
{
|
||||
// Act
|
||||
await _inputPipeline.ProcessInputAsync(null!);
|
||||
await _inputPipeline.ProcessInputAsync("");
|
||||
await _inputPipeline.ProcessInputAsync(" ");
|
||||
|
||||
// Assert
|
||||
_commandDispatcherMock.Verify(d => d.DispatchAsync(It.IsAny<string>()), Times.Never);
|
||||
_loggerMock.Verify(l => l.Info(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_CommandInput_DispatchesCommandAndResetsActiveCommand()
|
||||
{
|
||||
// Arrange
|
||||
var commandMock = new Mock<ICommand>();
|
||||
_commandDispatcherMock
|
||||
.Setup(d => d.DispatchAsync("testcmd"))
|
||||
.ReturnsAsync(commandMock.Object);
|
||||
|
||||
// Act
|
||||
await _inputPipeline.ProcessInputAsync("/testcmd");
|
||||
|
||||
// Assert
|
||||
_commandDispatcherMock.Verify(d => d.DispatchAsync("testcmd"), Times.Once);
|
||||
_loggerMock.Verify(l => l.Info(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_CommandInput_IfInteractiveCommand_SetsActiveCommand()
|
||||
{
|
||||
// Arrange
|
||||
var interactiveCommandMock = new Mock<IInteractiveCommand>();
|
||||
interactiveCommandMock.SetupGet(c => c.IsCompleted).Returns(false);
|
||||
_commandDispatcherMock
|
||||
.Setup(d => d.DispatchAsync("interactive"))
|
||||
.ReturnsAsync(interactiveCommandMock.Object);
|
||||
|
||||
// Act
|
||||
await _inputPipeline.ProcessInputAsync("/interactive");
|
||||
|
||||
// Assert
|
||||
var activeCommandField = typeof(InputPipeline).GetField("_activeCommand", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var activeCommandValue = activeCommandField!.GetValue(_inputPipeline);
|
||||
Assert.That(activeCommandValue, Is.SameAs(interactiveCommandMock.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_NonCommandInput_WithActiveInteractiveCommand_CallsHandleInputAsync()
|
||||
{
|
||||
// Arrange
|
||||
var interactiveCommandMock = new Mock<IInteractiveCommand>();
|
||||
interactiveCommandMock.SetupGet(c => c.IsCompleted).Returns(false);
|
||||
interactiveCommandMock.Setup(c => c.HandleInputAsync("user input")).Returns(Task.CompletedTask);
|
||||
|
||||
var activeCommandField = typeof(InputPipeline).GetField("_activeCommand", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
activeCommandField!.SetValue(_inputPipeline, interactiveCommandMock.Object);
|
||||
|
||||
// Act
|
||||
await _inputPipeline.ProcessInputAsync("user input");
|
||||
|
||||
// Assert
|
||||
interactiveCommandMock.Verify(c => c.HandleInputAsync("user input"), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_NonCommandInput_WithActiveInteractiveCommand_ResetsActiveCommand_WhenCompleted()
|
||||
{
|
||||
// Arrange
|
||||
var interactiveCommandMock = new Mock<IInteractiveCommand>();
|
||||
interactiveCommandMock.SetupSequence(c => c.IsCompleted)
|
||||
.Returns(false)
|
||||
.Returns(true);
|
||||
interactiveCommandMock.Setup(c => c.HandleInputAsync(It.IsAny<string>())).Returns(Task.CompletedTask);
|
||||
|
||||
var activeCommandField = typeof(InputPipeline).GetField("_activeCommand", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
activeCommandField!.SetValue(_inputPipeline, interactiveCommandMock.Object);
|
||||
|
||||
// Act & Assert 1
|
||||
await _inputPipeline.ProcessInputAsync("input1");
|
||||
Assert.That(interactiveCommandMock.Object, Is.SameAs(activeCommandField.GetValue(_inputPipeline)));
|
||||
|
||||
// Act & Assert 2
|
||||
await _inputPipeline.ProcessInputAsync("input2");
|
||||
Assert.That(activeCommandField.GetValue(_inputPipeline), Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ProcessInputAsync_NonCommandInput_WithoutActiveCommand_LogsInfo()
|
||||
{
|
||||
// Act
|
||||
await _inputPipeline.ProcessInputAsync("just text");
|
||||
|
||||
// Assert
|
||||
_loggerMock.Verify(l => l.Info("Введите /help, чтобы узнать доступные команды!"), Times.Once);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user