Skip to content

Testing GraphQL (with Hot Chocolate) with specifications (Reqnroll).

License

Notifications You must be signed in to change notification settings

jacobduijzer/graphql-specifications

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

.NET

GraphQL Specifications with Reqnroll

Welcome to the graphql-specifications repository! This project demonstrates how to test a GraphQL service built with HotChocolate using specifications and behavior-driven approaches with Reqnroll.

Why Specifications?

Specifications provide a structured, human-readable way to define and verify your GraphQL API’s behavior. By aligning tests with clear specifications, you can:

  • Ensure consistent and reliable API behavior.
  • Make tests easy to understand for both technical and non-technical stakeholders.
  • Promote collaboration and a shared understanding of the API’s functionality.

Repository Features

  • GraphQL Service: Built using HotChocolate, showcasing a sample domain.
  • Specifications: Written in plain language to describe API behavior.
  • Reqnroll Integration: Testing GraphQL queries and mutations against the specifications.
  • Implemented Scenarios:
    • Getting all books.
    • Searching for books by title, retrieving details, and checking stock.
    • Logging in as an owner or customer, with scope validation in the bearer token.
    • Adding books (restricted to logged-in store owners).

Getting Started

Follow these steps to explore and use this repository:

Prerequisites

Ensure you have the following installed:

Setup

  1. Clone the repository:
    git clone https://github.com/jacobduijzer/graphql-specifications.git
    cd graphql-specifications
  2. Install dependencies:
    dotnet restore
  3. Run the application:
     dotnet run --project ./src/Bookstore.Api --no-restore
  4. Open the GraphQL Playground at https://localhost:5011/graphql to test the queries and mutations.

Running Tests

  1. Run the tests:
    dotnet test

Query Examples

Get all books

query AllBooks {
books {
id
title
author
isbn
}
}

Search for a book by title

query BooksByTitle($titleSearch: String!) {
books(where: {
title: {
contains: $titleSearch
}
}) {
id
title
author
isbn
stock
}
}

Login

query login($email: String!, $password: String!) {
login(email: $email, password: $password) {
token
}
}

Custom WebApplicationFactory

The CustomWebApplicationFactory class is used to create a custom WebApplicationFactory for integration tests. This class is used to configure the test server with the required services and settings. It is also used to override registered services, in this case the StockService.

public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
services.AddSingleton<IStockService, StockServiceFake>();
});
}
public IBookstoreClient CreateBookstoreClient(string bearerToken = "")
{
var serviceCollection = new ServiceCollection();
serviceCollection
.AddBookstoreClient()
.ConfigureHttpClient(client =>
{
client.BaseAddress = new Uri(Server.BaseAddress, "graphql");
if(!string.IsNullOrEmpty(bearerToken))
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
},
c =>
{
c.ConfigurePrimaryHttpMessageHandler(() => Server.CreateHandler());
});
return serviceCollection
.BuildServiceProvider()
.GetRequiredService<IBookstoreClient>();
}
}

Specifications

Login

Feature: Having the ability to login as store owner or as customer
Scenario: Login as store owner
Given a store owner
When the store owner logs in with the username "owner@example.com" and password "password123"
Then the store owner is logged in with the correct "BookstoreOwner" claim
Scenario: Login as customer
Given a customer
When the customer logs in with the username "customer@example.com" and password "password123"
Then the customer is logged in with the correct "Customer" claim

Search for books

Feature: Searching for books
As an avid reader
I want to search for book information
So that I can find new books I want to read
Scenario: Going through a list of books
Given a customer, searching for books to buy
When the customer request the full list of books
Then the customer should find the following books:
| Title | Author |
| The Great Gatsby | F. Scott Fitzgerald |
| 1984 | George Orwell |
| To Kill a Mockingbird | Harper Lee |
Scenario: Searching books by title, getting stock information
Given a customer, searching for books to buy
When the customer is searching for books that contain "Great"
Then the customer should find the following books:
| Title | Author |
| The Great Gatsby | F. Scott Fitzgerald |
And the stock for this book should be 1

Add books

Feature: Adding books to the bookstore
As a bookstore owner
I want to add new books to the catalog
So I can sell new books
Scenario: A bookstore owner, trying to add a new book without authorization
Given a book with the title "David Copperfield"
And the author "Charles Dickens"
And the isbn "9780140439441"
When the bookstore owner adds a new book to the catalog
Then the bookstore owner will get an error message
Scenario: A bookstore owner adding a new book to the catalog
Given a book with the title "David Copperfield"
And the author "Charles Dickens"
And the isbn "9780140439441"
When the bookstore owner is logged in with the username "owner@example.com" and password "password123"
And the bookstore owner adds a new book to the catalog
Then the book is added to the catalog
And the newly added book will be returned

Links

License

This project is licensed under the MIT License. See the LICENSE file for details.


For more insights, check out my blog post on using specifications with Reqnroll to test GraphQL services. (Coming soon!)

Happy Testing! 🚀

About

Testing GraphQL (with Hot Chocolate) with specifications (Reqnroll).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published