Testowanie CRUDa

Odpowiedz Nowy wątek
2019-07-17 08:48
0

Mam taki kod:

var review = await _db.Reviews.FindAsync(request.ProductId, request.CustomerId);

if (review == null)
    return new Result(ErrorType.NotValid, "Recenzja nie istnieje.");

_db.Reviews.Remove(review);
await _db.SaveChangesAsync(cancellationToken);

return Result.SuccessfulResult;

Czy warto go testować? Na pierwszy rzut oka widać, że będzie działał. Testy jednostkowe do niego kosztują 70 linijek, podczas gdy cała klasa z tym kodem ma ich 35. Czy testy nie powinno się pisać tylko dla jakiejś skomplikowanej logiki? W mojej aplikacji mam praktycznie same CRUDy. Co ja mam w niej testować?

Pozostało 580 znaków

2019-07-17 09:39
2

Też mam same CRUDy ale dzięki testom czasami wyłapuje jakieś brzegowe przypadki złego działania.

Pozostało 580 znaków

2019-07-17 09:48
1

Testy jednostkowe do niego kosztują 70 linijek

Testy jednostkowe na zasadzie zrób mocki do wszystkiego i niech się dzieje wola nieba? :-P


edytowany 1x, ostatnio: Patryk27, 2019-07-17 09:48

Pozostało 580 znaków

2019-07-17 09:51
0
Patryk27 napisał(a):

Testy jednostkowe do niego kosztują 70 linijek

Testy jednostkowe na zasadzie zrób mocki do wszystkiego i niech się dzieje wola nieba? :-P

Jeśli to jest EF Core to pewnie EFInMemory i zapełnia danymi i testuje poprawne zachowanie

Pozostało 580 znaków

2019-07-17 09:52
0

@Patryk27: Wyglądają tak:

using System;
using System.Threading;
using System.Threading.Tasks;
using MyStore.Application.Interfaces.Security;
using MyStore.Application.Products.CommandHandlers;
using MyStore.Application.Products.Commands;
using MyStore.Common.Types.Results;
using MyStore.Database;
using MyStore.Model;
using MyStore.Tests.Infrastructure;
using Shouldly;
using Xunit;

namespace MyStore.Tests.Products.CommandHandlers
{
    [Collection(nameof(ApplicationCollection))]
    public class DeleteReviewHandlerTests : IDisposable
    {
        private readonly ApplicationDbContext _db;
        private readonly IAuthContext _auth;

        public DeleteReviewHandlerTests(ApplicationFixture fixture)
        {
            _db = fixture.Db;
            _auth = fixture.Auth;
        }

        [Fact]
        public async Task Should_Not_Delete_Review_When_Review_Does_Not_Exist()
        {
            var handler = new DeleteReviewHandler(_db, _auth);

            var command = new DeleteReview(100, _auth.GetCurrentCustomerId());

            var result = await handler.Handle(command, CancellationToken.None);

            result.IsSuccessful.ShouldBe(false);
            result.Error.Type.ShouldBe(ErrorType.NotValid);
        }

        [Fact]
        public async Task Should_Delete_Review()
        {
            var review = new Review
            {
                ProductId = 1,
                AuthorId = _auth.GetCurrentCustomerId(),
                Stars = 5,
                Content = "Test Content"
            };

            _db.Reviews.Add(review);
            _db.SaveChanges();

            var handler = new DeleteReviewHandler(_db, _auth);

            var command = new DeleteReview(review.ProductId, review.AuthorId);

            var result = await handler.Handle(command, CancellationToken.None);

            result.IsSuccessful.ShouldBe(true);
        }

        public void Dispose()
        {
            _db.Reviews.RemoveRange();
            _db.SaveChanges();
        }
    }
}

Pozostało 580 znaków

2019-07-17 09:58
1

Ja bym sprawdzał czy na pewno obiekt został usunięty z bazy. Bo jak pominiesz w kodzie savechangs to test też przejdzie :)

Pozostało 580 znaków

2019-07-17 09:59
0

@szydlak: Wiem, miałem to dziś dopisać. ;) W ogóle testy i kod są trochę rozsynchronizowane ze sobą, więc nie analizujcie, czy wszystko ma sens, chodzi jedynie o ideę. ;)

Pozostało 580 znaków

2019-07-17 13:46
1

to bardziej integracyjne niż jednostkowe :P chyba, że zrobisz abstakcję na usuwanie, pobieranie i dodawanie ;) :D

Pozostało 580 znaków

2019-08-23 20:59
0

Czytam sobie ostatnio o testach integracyjnych i zastanawiam się, czy nie lepiej byłoby ich użyć w zamian "jednostkowych" (takich jak wyżej). Żeby było jasne: mam na myśli coś takiego: https://docs.microsoft.com/pl[...]ion-tests?view=aspnetcore-2.2
Aby zwiększyć wydajność mógłbym podpiąć SQLite'a in-memory i skorzystać z collection fixtures. Miałbym np taki kod:

[Fact]
public async Task Should_Register_User()
{
    var command = new Register("User1", "[email protected]", "Secret123");

    var response = await _client.PostAsync("/api/auth/register", GetPayload(command));

    response.EnsureSuccessStatusCode();
}

Różnica w wydajności nie powinna być duża w takim przypadku. @Aventus pisał kiedyś, że jego zdaniem testy jednostkowe należy ograniczyć do minimum i stosować je tylko tam, gdzie faktycznie przynoszą jakieś korzyści. Czy testy integracyjne wyglądają wówczas tak, że testuje się każdą ścieżkę egzekucji żadania osobno? Testowanie jedynie happy path to chyba za mało.

edytowany 1x, ostatnio: nobody01, 2019-08-23 21:03

Pozostało 580 znaków

2019-08-23 22:29
0

Gwoli ścisłości, ja opowiadałem się za czymś pośrednim między testem jednostkowym a integracyjnym. W takim przypadku test uderza w endpoint (za pomocą hosta w pamięci opisanego w Twoim linku), natomiast wszelkie inne zależności których w konkretnym teście nie chcę sprawdzać podmieniam- czy to za pomocą biblioteki mockującej czy "manualnie" dostarczając testową implementację intefejsu.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.

Pozostało 580 znaków

2019-08-23 22:35
0

@Aventus: Moglbys podac jakis przyklad? Nie moge sobie tego wyobrazic :(

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0