Problem z testowaniem logowania XUnit

0

Witam mam pewien problem, ponieważ od niedawna uczę się jak pisać testy i napotkałem na pewien problem, którego nie jestem w stanie rozwiązać.

Chodzi mi dokładnie o to, że napisałem test, który ma sprawdzać, czy Kontroler, który jest odpowiedzialny za logowanie ma zwracać kod 200, czyli Ok jednak podczas wykonywania testu jest zwracany kod 500, czyli błąd serwera.

Używam bazy, która ładuję się do pamięci i wydaje mi się, że to prawdopodobnie z tym jest problem, ponieważ gdy robiłem test na normalnej bazie danych to test przechodził pomyślnie.

Poniżej wklejam kod, abyście mogli sprawdzić co może być nie tak.

AccountControllerTests:

    public class AccountControllerTests : IClassFixture<WebApplicationFactory<Program>>
    {
        private HttpClient Client { get; set; }

        public AccountControllerTests(WebApplicationFactory<Program> factory)
        {
            Client = factory
                .WithWebHostBuilder(builder =>
                {
                    builder.ConfigureServices(services =>
                    {
                        var dbContext = services
                            .SingleOrDefault(x => x.ServiceType == typeof(DbContextOptions<DiaryDbContext>));
                        services.Remove(dbContext);

                        services.AddDbContext<DiaryDbContext>(options => options.UseInMemoryDatabase("DiaryDb"));
                    });
                })
                .CreateClient();
        }

        [Fact]
        public async Task Login_WithoutParams_ReturnOkRequest()
        {
            var model = new LoginViewModel()
            {
                Email = "[email protected]",
                Password = "user"
            };

            var json = JsonConvert.SerializeObject(model);

            var httpContext = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await Client.PostAsync("/api/Account/Login", httpContext);

            response.StatusCode.Should().Be(System.Net.HttpStatusCode.OK);
        }
    }

AccountController:

    public class AccountController : ControllerBase
    {
        private readonly AccountService AccountService;

        public AccountController(AccountService AccountService)
        {
            this.AccountService = AccountService;
        }

        [HttpPost]
        [Route("Register")]
        public async Task<IActionResult> Register(LoginViewModel model)
        {
            await AccountService.Register(model);

            return Ok();
        }

        [HttpPost]
        [Route("Login")]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            var token = await AccountService.Login(model);

            return Ok(token);
        }
    }

AccountService:

        public async Task<string> Login(LoginViewModel UserModel)
        {
            if (UserModel is null)
            {
                throw new ArgumentNullException("Invalid data");
            }

            var User = await DiaryDbContext.Person
                .Include(x => x.Roles)
                .ThenInclude(x => x.Role)
                .SingleOrDefaultAsync(x => x.Email == UserModel.Email);

            if (User is null)
            {
                throw new ArgumentNullException("Invalid data");
            }

            var Password = PasswordHasher.VerifyHashedPassword(UserModel, User.PasswordHash, UserModel.Password);

            if (Password == PasswordVerificationResult.Failed)
            {
                throw new ArgumentOutOfRangeException("Invalid email or password");
            }

            var claims = new List<Claim>()
            {
                new Claim(ClaimTypes.NameIdentifier, User.UserUUID.ToString()),
                new Claim(ClaimTypes.Name, User.Email)
            };

            foreach (var role in User.Roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role.Role.Name));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Auth.Key));
            var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddHours(10);

            var token = new JwtSecurityToken(Auth.Issuer,
                Auth.Issuer,
                claims,
                expires: expires,
                signingCredentials: cred);

            var tokenHandler = new JwtSecurityTokenHandler();

            return tokenHandler.WriteToken(token);
        }
0

Ale wiesz, że możesz debugować testy i sprawdzić w którym miejscu i dlaczego idzie ta 500tka?

Btw czemu nie masz tam w akcji logowania atrubutu [FromBoody]?

0

@szydlak:

szydlak napisał(a):

Ale wiesz, że możesz debugować testy i sprawdzić w którym miejscu i dlaczego idzie ta 500tka?

500tka pojawia się przy zmiennej response a w komunikacje mam tylko Internal Server Error, ale mówi mi to tyle że kontroler nie istnieje co wydaje mi się dziwne, ponieważ jak sobie napisałem inny test dotyczący rejestracji to wszystko działa dobrze

Btw czemu nie masz tam w akcji logowania atrubutu [FromBoody]?

Fakt tutaj małe niedociągnięcie, ponieważ wcześniej nie wiedziałem, do czego się używa [FromBody] dlatego go nie używałem, ale doczytałem sobie trochę na stackoverflow i dokumentacji microsoft i już wstawiłem to do mojego kodu

EDIT:
Kiedy usunąłem funkcje serwisu która jest odpowiedzialna za logowanie to test zadziałał więc prawdopodobnie ten błąd jest związany z samą funkcją logowania tylko nie do końca rozumiem co jest przyczyną

3

@daniel500013:

daniel500013 napisał(a):

500tka pojawia się przy zmiennej response a w komunikacje mam tylko Internal Server Error, ale mówi mi to tyle że kontroler nie istnieje co wydaje mi się dziwne, ponieważ jak sobie napisałem inny test dotyczący rejestracji to wszystko działa dobrze

Ale daj breakepoint na początku akcji w kontrolerze i debuguj podczas testu

0

@szydlak:

szydlak napisał(a):

Ale daj breakepoint na początku akcji w kontrolerze i debuguj podczas testu

A dobra już widzę, w czym jest problem w badzie danych nie ma takiego użytkownika którego podałem ponieważ baza danych jest tworzona w pamięci i nie ma tam żadnych rekordów użytkownika w odróżnieniu od mojej lokalnej bazy danych.

Dzięki za pomoc! Nie wiedziałem, że podczas debugowania w testach normalnie mogę sobie sprawdzać rzeczy w serwisach, kontrolerach i tak dalej. Teraz myślę, że już sobie poradzę jeszcze raz wielkie dzięki :)

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