4 dicas de como usar o ChatGPT para Devs
Nesse artigo vou mostrar 4 maneiras de como eu uso ChatGPT no meu dia a dia. E no video abaixo você pode ver mais detalhes de como eu fiz tudo abaixo
1 – Montar SQLs
Recentemente eu resolvi um bug para identificar e renomear valores duplicados. Vamos usar como exemplo a tabela abaixo
Id | Numero |
---|---|
1 | 0001 |
2 | 0001 |
3 | 0001 |
Note que a coluna Numero tem valores duplicados
Meu SQL tem que pegar o valor dessa coluna e concatenar com algum index para ficar assim “0001_1”, “0001_2” e assim sucessivamente. O valor da primeira linha não deve ser alterado e deve continuar “0001”
Para resolver fiz o seguinte prompt no ChatGPT
Crie um script sql para alterar valores duplicados em uma coluna de uma tabela. A tabela vai se chamar Pedido e as colunas são Id do tipo int, Numero do tipo varchar(15). Esse script deve conter begin tran
Esse foi o resultado
BEGIN TRANSACTION;
-- Atualizar valores duplicados na coluna Numero
WITH NumerosDuplicados AS (
SELECT
Id,
Numero,
ROW_NUMBER() OVER(PARTITION BY Numero ORDER BY Id) AS RowNum
FROM
Pedido
)
UPDATE Pedido
SET Numero = CONCAT(Numero, '_', Id)
FROM Pedido AS p
INNER JOIN NumerosDuplicados AS d
ON p.Id = d.Id
WHERE d.RowNum > 1;
COMMIT;
Você também pode argumentar informando que algo está errado, como por exemplo
o update não está respeitando o RowNum
E esse foi o resultado
BEGIN TRANSACTION;
-- Seleciona e altera valores duplicados na coluna Numero
WITH NumerosDuplicados AS (
SELECT
Id,
Numero,
ROW_NUMBER() OVER(PARTITION BY Numero ORDER BY Id) AS RowNum
FROM
Pedido
)
UPDATE Pedido
SET Numero = CONCAT(NumerosDuplicados.Numero, '_', NumerosDuplicados.RowNum)
FROM Pedido
INNER JOIN NumerosDuplicados
ON Pedido.Id = NumerosDuplicados.Id
WHERE NumerosDuplicados.RowNum > 1;
COMMIT;
2 – Criação de teste unitário
Vamos usar como exemplo a classe abaixo
import { z } from "zod";
import { User } from "@/application/authetication/entities/User";
import { type UserRepository } from "@/application/authetication/repositories/UserRepository";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Toast } from "@/infra/Notification";
export const CreateUserSchema = z.object({
email: z.string().email(),
password: z.string(),
});
export type CreateUserInput = z.infer<typeof CreateUserSchema>;
export class CreateUserHandler {
constructor(readonly userRepo: UserRepository, readonly router: AppRouterInstance, readonly toast: Toast) {}
async execute(input: CreateUserInput): Promise<User | null> {
try {
const user = await this.userRepo.create(new User("", input.email, false), input.password);
if (!user) {
throw new Error("Ocorreu um erro ao tentar criar sua conta. Atualize a página e tente novamente.");
}
this.toast.showSuccess("Conta criada com sucesso.");
this.router.push("/login");
this.router.refresh();
return user;
} catch (error) {
this.toast.showError((error as Error).message);
return null;
}
}
}
E fiz o seguinte prompt
Dado a classe abaixo, crie testes unitários utilizando vitest
import { z } from "zod";
import { User } from "@/application/authetication/entities/User";
import { type UserRepository } from "@/application/authetication/repositories/UserRepository";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Toast } from "@/infra/Notification";
export const CreateUserSchema = z.object({
email: z.string().email(),
password: z.string(),
});
export type CreateUserInput = z.infer<typeof CreateUserSchema>;
export class CreateUserHandler {
constructor(readonly userRepo: UserRepository, readonly router: AppRouterInstance, readonly toast: Toast) {}
async execute(input: CreateUserInput): Promise<User | null> {
try {
const user = await this.userRepo.create(new User("", input.email, false), input.password);
if (!user) {
throw new Error("Ocorreu um erro ao tentar criar sua conta. Atualize a página e tente novamente.");
}
this.toast.showSuccess("Conta criada com sucesso.");
this.router.push("/login");
this.router.refresh();
return user;
} catch (error) {
this.toast.showError((error as Error).message);
return null;
}
}
}
E esse foi o resultado
import { describe, it, expect, vi, beforeEach } from "vitest";
import { User } from "@/application/authetication/entities/User";
import { CreateUserHandler, CreateUserInput } from "@/application/authetication/handlers/CreateUserHandler";
import { type UserRepository } from "@/application/authetication/repositories/UserRepository";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Toast } from "@/infra/Notification";
describe("CreateUserHandler", () => {
let userRepo: UserRepository;
let router: AppRouterInstance;
let toast: Toast;
let handler: CreateUserHandler;
beforeEach(() => {
// Mock das dependências
userRepo = {
create: vi.fn()
} as unknown as UserRepository;
router = {
push: vi.fn(),
refresh: vi.fn()
} as unknown as AppRouterInstance;
toast = {
showSuccess: vi.fn(),
showError: vi.fn()
} as unknown as Toast;
handler = new CreateUserHandler(userRepo, router, toast);
});
it("deve criar o usuário e redirecionar para a página de login em caso de sucesso", async () => {
const input: CreateUserInput = { email: "[email protected]", password: "password123" };
const newUser = new User("1", input.email, false);
(userRepo.create as vi.Mock).mockResolvedValue(newUser);
const result = await handler.execute(input);
expect(userRepo.create).toHaveBeenCalledWith(newUser, input.password);
expect(toast.showSuccess).toHaveBeenCalledWith("Conta criada com sucesso.");
expect(router.push).toHaveBeenCalledWith("/login");
expect(router.refresh).toHaveBeenCalled();
expect(result).toBe(newUser);
});
it("deve mostrar um erro e retornar null se o repositório retornar null", async () => {
const input: CreateUserInput = { email: "[email protected]", password: "password123" };
(userRepo.create as vi.Mock).mockResolvedValue(null);
const result = await handler.execute(input);
expect(toast.showError).toHaveBeenCalledWith("Ocorreu um erro ao tentar criar sua conta. Atualize a página e tente novamente.");
expect(result).toBeNull();
});
it("deve mostrar uma mensagem de erro e retornar null se ocorrer um erro", async () => {
const input: CreateUserInput = { email: "[email protected]", password: "password123" };
const errorMessage = "Erro de criação";
(userRepo.create as vi.Mock).mockRejectedValue(new Error(errorMessage));
const result = await handler.execute(input);
expect(toast.showError).toHaveBeenCalledWith(errorMessage);
expect(result).toBeNull();
});
});
Obviamente pode ser que precise de algum ajuste conforme eu fiz no vídeo acima, mas o resultado já me atendeu completamente e me fez economizar o tempo de escrever todos esses testes e criar todos os mocks.
3 – Transformar uma classe para um JSON
Vez ou outra quando estamos criando algum endpoint em alguma api, criamos uma classe para ser o input desse request. E aí precisamos de gerar um json para colocar no body do request com base nessa classe. É aí que o ChatGPT entra.
Vamos pegar como exemplo a classe abaixo escrita em C#
public class Pessoa
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Eu fiz esse prompt para gerar o JSON
Transforme essa classe em c# em um json
public class Pessoa
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
E esse foi o resultado
{
"Id": 123456,
"FirstName": "João",
"LastName": "Silva"
}
Lembrando que no C# o formato que usamos é o camelCase para esses casos, eu fiz outro prompt para alterar esse formato
Altere o json para o formato camel case
E esse foi o resultado
{
"id": 123456,
"firstName": "João",
"lastName": "Silva"
}
E o melhor é que ele ainda popula com dados fictícios para facilitar o teste.
4 – Gerar dados fictícios
Recentemente desenvolvi uma nova feature para importação de dados em um sistema, e gerar um um arquivo csv varios registros para teste não é uma tarefa fácil.
Para resolver isso fiz o seguinte prompt para o ChatGPT
gerar aquivo csv com 100 registros com os campos nome, cpf e data de nascimento
Conforme você pode ver no vídeo acima, ele gerou o csv com todos os dados que eu precisava para o meu teste e ainda mostrou em um código como ele fez para gerar.
Isso é fantástico.
Conclusão
Essas inteligencias artificiais podem ser de grande valia para o nosso dia a dia, mas você ainda precisa saber pensar. Se você não sabe escrever o que você quer, elas vão te responder qualquer coisa.
Sem contar que você pode economizar um bom tempo no seu dia a dia.
E você, como está usando o ChatGPT no seu dia a dia?