Probar código que acepta context.Context
Las funciones que aceptan context.Context necesitan pruebas para éxito, tiempo de espera excedido y cancelación manual, no solo el camino feliz.
Busca en todas las páginas de la documentación
Las funciones que aceptan context.Context necesitan pruebas para éxito, tiempo de espera excedido y cancelación manual, no solo el camino feliz.
El paquete context de Go y los ayudantes de testing hacen que esos caminos sean deterministas sin dormir en CI.
Usa context.WithTimeout o WithCancel en las pruebas para generar resultados de ctx.Err().
Prefiere fakes basados en canales sobre time.Sleep al probar la propagación de cancelación.
Aserción con errors.Is para context.Canceled y context.DeadlineExceeded.
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
func TestWorkCanceled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
err := Work(ctx)
if !errors.Is(err, context.Canceled) {
t.Fatalf("got %v, want Canceled", err)
}
}Cuándo usar esto:
ctx junto con entradas normales.httptest y contextos de solicitud.package work_test
import (
"context"
"errors"
"testing"
"time"
"example.com/ctxdemo/work"
)
func TestFetchDeadline(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
defer cancel()
err := work.Fetch(ctx, slowStub{})
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("got %v", err)
}
}
func TestFetchCancel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(5 * time.Millisecond)
cancel()
}()
err := work.Fetch(ctx, slowStub{})
if !errors.Is(err, context.Canceled) {
t.Fatalf("got %v", err)
}
}
type slowStub struct{}
func (slowStub) Run(ctx context.Context) error {
select {
case <-time.After(200 * time.Millisecond):
return nil
case <-ctx.Done():
return ctx.Err()
}
}Lo que esto demuestra:
DeadlineExceeded de un WithTimeout corto sin esperas largas en la ruta de aserción.cancel() manual desde otra gorrutina simula la desconexión del cliente.ctx de la misma manera que lo haría la E/S de producción.errors.Is mantiene las aserciones estables si los errores se envuelven con %w.t.Context() (Go 1.24+) proporciona un contexto cancelado cuando la prueba termina, útil para pruebas de integración.httptest.NewRequest adjunta un contexto de fondo; reemplázalo con req.WithContext(ctx) para casos de cancelación.| Escenario | Configuración | Esperado |
|---|---|---|
| Éxito | context.Background() | error nil |
| Tiempo de espera agotado | WithTimeout(..., 1ms) | DeadlineExceeded |
| Cancelación manual | cancel() antes de la llamada | Canceled |
| Padre cancelado | cancelar padre de hijo | Err() del hijo establecido |
| Causa adjunta | WithCancelCause | context.Cause(ctx) |
req := httptest.NewRequest(http.MethodGet, "/", nil)
ctx, cancel := context.WithCancel(req.Context())
cancel()
req = req.WithContext(ctx)
rec := httptest.NewRecorder()
handler(rec, req)
// esperar que no haya cuerpo de respuesta en la cancelaciónfunc wait(ctx context.Context, d time.Duration) error {
timer := time.NewTimer(d)
defer timer.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
return nil
}
}Siempre detén los temporizadores en pruebas y producción para evitar fugas.
cancel() inmediato o tiempos de espera de 1-20 ms.==. Solución: errors.Is y errors.As.-race. Solución: defer cancel() siempre.WithContext.cancel(). Solución: contexto por subprueba con cuidado de t.Parallel().| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
t.Context() | Limpieza automática al final de la prueba | Control detallado del tiempo de cancelación |
| Fake de interfaz con canal bloqueante | Cancelación determinista | Funciones puras simples |
| Prueba de integración con DB real | Verificación de cancelación del controlador | Pruebas de lógica a nivel de unidad |
testing/quick | Aleatorización de plazos | Pruebas de tabla legibles |
time.Sleep en pruebas | Nunca preferido | - |
Prueba las funciones que se ramifican en ctx.Done() o pasan ctx a las dependencias.
Los ayudantes puros que solo reenvían ctx pueden depender de pruebas de integración.
Adjunta valores en la configuración de la prueba con los mismos ayudantes de clave que usa la producción.
Asegura que los accesores devuelvan los metadatos esperados.
Sí - assert.ErrorIs(t, err, context.Canceled) se lee bien en pruebas de tabla.
Construye un contexto con tiempo de espera e invoca el interceptor con httptest o los búferes de prueba de grpc.
Verifica el mapeo de codes.DeadlineExceeded.
Cancela con WithCancelCause y verifica errors.Is(context.Cause(ctx), wantCause).
Usa context.Background() a menos que estés midiendo específicamente la sobrecarga de cancelación.
Reporta -benchmem por separado de las pruebas de cancelación.
Siempre defer cancel() para WithTimeout y detén los temporizadores en los bucles select.
Construye un ctx nuevo por fila dentro de t.Run para evitar la contaminación entre pruebas.
Cancela el padre, deriva context.WithoutCancel(parent) y verifica que el hijo aún se ejecuta brevemente.
Verifica que los valores del padre sean visibles.
Sí - ejecuta pruebas de cancelación con -race para detectar gorrutinas que ignoran Done().
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado de GC Green Tea, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica los objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026