Ядро .NET лучше пишет модульные тесты с Xunit + Autofixture + Moq - PullRequest
1 голос
/ 02 октября 2019

В .NET Core для модульного тестирования я использую Xunit, Moq и Autofixture. Но даже с ними я вижу, что мои модульные тесты усложняются и занимают время.

Может быть, кто-то может сказать мне, если есть какие-либо способы сделать этот тест меньше?

    [Fact]
    public async Task Verify_NotAuthorised_NoServiceSendInvoked()
    {
        // Arrange
        var fixture = new Fixture()
            .Customize(new AutoMoqCustomization());

        var sut = fixture.Create<VerificationService>();

        var mockApiBuilder = fixture.Freeze<Mock<IApiEntityBuilder>>();
        //init mocked mockSendServiceOne, so later I could check if it was invoked or not
        var mockSendServiceOne = fixture.Freeze<Mock<ISendServiceOne>>();

        mockApiBuilder.Setup(x => x.Verification(It.IsAny<string>(), It.IsAny<string>()))
            .Returns(fixture.Create<VerificationEntity>());

        var call = fixture.Freeze<Mock<ISendServiceTwo>>();
        call.Setup(x => x.IsSuccessful()).Returns(false);

        // Act
        await sut.Verify(fixture.Create<string>(), fixture.Create<string>());

        // Assert
        mockSendServiceOne .Verify(x => x.Call(It.IsAny<SendServiceOneEntity>()), Times.Never);
    }

Тестированиесам метод

        public async Task<CreatedEntity> Verify(string dataOne, string dataTwo)
        {
           await _someCaller.Call(_apiEntityBuilder.Verification(dataOne, dataTwo));
           _someCaller.CreatePayment();

           if (!_someCaller.IsSuccessful()) return _someCaller.CreatedEntity;

           await mockSendServiceOne.Call(_apiEntityBuilder.Call(_someCaller.CreatedEntity.SpecificData));

           return _someCaller.CreatedEntity;
        }

Здесь я тестирую, если isSuccessful () возвращает fasle, тогда не следует вызывать mockSendServiceOne.Call.

Может ли кто-нибудь дать мне отзыв о том, как написать более качественные модульные тесты,Потому что только для этой небольшой проверки кода мне пришлось написать много кода для его проверки.

1 Ответ

1 голос
/ 09 октября 2019

Вы можете использовать Теории AutoData . (Ссылки на отличный пост Марка Симана об этой конкретной ситуации).

Короче говоря, AutoFixture имеет встроенный атрибут AutoData, от которого вы можете наследовать, а затем настраивать прибор с помощью AutoMoqCustomization.

Вы украшаете свой тестовый метод ([Теория]) этим атрибутом, и теперь автофиксатор автоматически генерирует любой параметр, который вы указываете для своего тестового метода.

Когда вы будете использовать метод Freeze() для генерации элемента,Вы помещаете атрибут [Frozen] перед параметром.

Вот пример того, как это сделать:

public class TheTests
{
    [Theory]
    [AutoDomainData]
    public void Verify_WhatWeWannaTest_CallsTheMethodOnTheDependency([Frozen] Mock<ITheDependency> dependency, WhatWeWannaTest sut)
    {
        // Act
        sut.CallTheDependency();

        // Assert
        dependency.Verify(x => x.TheMethod());
    }
}

// Create a AutoData attribute customized with Moq
public class AutoDomainDataAttribute : AutoDataAttribute
{
    public static IFixture FixtureFactory()
    {
        var f = new Fixture();
        // I like members of interfaces to be configured, so i set it her
        f.Customize(new AutoMoqCustomization { ConfigureMembers = true });
        return f;
    }

    public AutoDomainDataAttribute() : base(FixtureFactory) { }
}

// Simple class we can test
public class WhatWeWannaTest
{
    private readonly ITheDependency _theDependency;

    public WhatWeWannaTest(ITheDependency theDependency) { _theDependency = theDependency; }

    public void CallTheDependency()
    {
        _theDependency.TheMethod();
    }
}

// Simple dependency for WhatWeWannaTest
public interface ITheDependency
{
    int TheMethod();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...