avatarJay C Wells

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8645

Abstract

<span class="hljs-keyword">async</span> <span class="hljs-title function_">delete</span>(<span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>): <span class="hljs-title class_">Promise</span><<span class="hljs-title class_">Item</span>> { <span class="hljs-keyword">const</span> item = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">itemModel</span>.<span class="hljs-title function_">findByIdAndRemove</span>(id); <span class="hljs-keyword">if</span> (!item) { <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">NotFoundException</span>(<span class="hljs-string">'Item not found'</span>); } <span class="hljs-keyword">return</span> item; } }</pre></div><p id="61ef">3. Controller with Validation:</p><p id="425a">Inside <code>item.controller.ts</code>:</p><div id="dace"><pre><span class="hljs-keyword">import</span> { Body, Controller, Get, Post, Put, Delete, Param, NotFoundException, BadRequestException, ParseUUIDPipe } from <span class="hljs-string">'@nestjs/common'</span>; <span class="hljs-keyword">import</span> { CreateItemDto } from <span class="hljs-string">'./create-item.dto'</span>; <span class="hljs-keyword">import</span> { UpdateItemDto } from <span class="hljs-string">'./update-item.dto'</span>; <span class="hljs-keyword">import</span> { ItemService } from <span class="hljs-string">'./item.service'</span>; <span class="hljs-keyword">import</span> { Item } from <span class="hljs-string">'./item.schema'</span>;

<span class="hljs-meta">@Controller(<span class="hljs-string">'items'</span>)</span> export <span class="hljs-keyword">class</span> <span class="hljs-title class_">ItemController</span> { <span class="hljs-keyword">constructor</span>(<span class="hljs-keyword">private</span> readonly itemService: ItemService) { }

<span class="hljs-meta">@Post()</span>
async create(<span class="hljs-meta">@Body()</span> createItemDto: CreateItemDto): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.create(createItemDto);
}

<span class="hljs-meta">@Get()</span>
async findAll(): Promise&lt;Item[]&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.findAll();
}

<span class="hljs-meta">@Get(<span class="hljs-string">':id'</span>)</span>
async findOne(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.findOne(id);
}

<span class="hljs-meta">@Put(<span class="hljs-string">':id'</span>)</span>
async update(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string, <span class="hljs-meta">@Body()</span> updateItemDto: UpdateItemDto): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.update(id, updateItemDto);
}

<span class="hljs-meta">@Delete(<span class="hljs-string">':id'</span>)</span>
async delete(<span class="hljs-meta">@Param(<span class="hljs-string">'id'</span>)</span> id: string): Promise&lt;Item&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.itemService.delete(id);
}

}</pre></div><p id="7771">4. Activate auto-validation:</p><p id="61fc">update the fille main.ts</p><div id="fe08"><pre><span class="hljs-keyword">import</span> { <span class="hljs-title class_">NestFactory</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">AppModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.module'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">ValidationPipe</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">bootstrap</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> <span class="hljs-title class_">NestFactory</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">AppModule</span>); app.<span class="hljs-title function_">useGlobalPipes</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">ValidationPipe</span>()); <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">listen</span>(<span class="hljs-number">3000</span>); } <span class="hljs-title function_">bootstrap</span>();</pre></div><h1 id="a2cc">Unit Testing:</h1><p id="0fac">1. Setup:</p><p id="23ed">Install required packages:</p><div id="89f0"><pre>npm install @nestjs/testing</pre></div><p id="2a92">2. Testing the Service:</p><p id="bc15">In the <code>item.service.spec.ts</code>:</p><div id="b87f"><pre><span class="hljs-keyword">import</span> { Test, TestingModule } from <span class="hljs-string">'@nestjs/testing'</span>; <span class="hljs-keyword">import</span> { ItemService } from <span class="hljs-string">'./item.service'</span>; <span class="hljs-keyword">import</span> { getModelToken } from <span class="hljs-string">'@nestjs/mongoose'</span>; <span class="hljs-keyword">import</span> { NotFoundException } from <span class="hljs-string">'@nestjs/common'</span>;

describe(<span class="hljs-string">'ItemService'</span>, () => { let service: ItemService; let mockItemModel;

beforeEach(<span class="hljs-keyword">async</span> () => { mockItemModel = { find: jest.fn(), findById: jest.fn(), findByIdAndUpdate: jest.fn(), findByIdAndRemove: jest.fn(), create: jest.fn(), };

<span class="hljs-keyword">const</span> module: TestingModule = <span class="hljs-keyword">await</span> Test.createTestingModule({
  providers: [
    ItemService,
    {
      provide: getModelToken(<span class="hljs-string">'Item'</span>),
      useValue: mockItemModel,
    },
  ],
}).compile();

service = module.<span class="hljs-keyword">get</span>&lt;ItemService&gt;(ItemService);

});

it(<span class="hljs-string">'should be defined'</span>, () => { expect(service).toBeDefined(); });

describe(<span class="hljs-string">'findAll'</span>, () => { it(<span class="hljs-string">'should return an array of items'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = []; mockItemModel.find.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.findAll()).toBe(result); }); });

describe(<span class="hljs-string">'findOne'</span>, () => { it(<span class="hljs-string">'should retrieve an item by its ID'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'ItemName'</span> }; mockItemModel.findById.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.findOne(<span class="hljs-string">'some-id'</span>)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findById.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.findOne(<span class="hljs-string">'some-id'</span>)).rejects.toThrow(NotFoundException);
});

});

describe(<span class="hljs-string">'create'</span>, () => { it(<span class="hljs-string">'should successfully insert an item'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> createItemDto = { name: <span class="hljs-string">'NewItem'</span> }; mockItemModel.create.mockResolvedValue(createItemDto); expect(<span class="hljs-keyword">await</span> service.create(createItemDto)).toBe(createItemDto); }); });

describe(<span class="hljs-string">'update'</span>, () => { it(<span class="hljs-string">'should update an item'</span>, <span class="hljs-keyword">async</span> () =&

Options

gt; { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'UpdatedName'</span> }; <span class="hljs-keyword">const</span> updateItemDto = { name: <span class="hljs-string">'UpdatedName'</span> }; mockItemModel.findByIdAndUpdate.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.update(<span class="hljs-string">'some-id'</span>, updateItemDto)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findByIdAndUpdate.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.update(<span class="hljs-string">'some-id'</span>, {})).rejects.toThrow(NotFoundException);
});

});

describe(<span class="hljs-string">'delete'</span>, () => { it(<span class="hljs-string">'should delete an item by its ID'</span>, <span class="hljs-keyword">async</span> () => { <span class="hljs-keyword">const</span> result = { _id: <span class="hljs-string">'some-id'</span>, name: <span class="hljs-string">'ItemToDelete'</span> }; mockItemModel.findByIdAndRemove.mockResolvedValue(result); expect(<span class="hljs-keyword">await</span> service.delete(<span class="hljs-string">'some-id'</span>)).toBe(result); });

it(<span class="hljs-string">'should throw NotFoundException when item does not exist'</span>, <span class="hljs-keyword">async</span> () =&gt; {
  mockItemModel.findByIdAndRemove.mockResolvedValue(<span class="hljs-keyword">null</span>);
  <span class="hljs-keyword">await</span> expect(service.delete(<span class="hljs-string">'some-id'</span>)).rejects.toThrow(NotFoundException);
});

}); });</pre></div><h1 id="ceb6">E2E Testing:</h1><p id="33a2">Testing the Service:</p><p id="4f53">create new file <code>item.e2e-spec.ts</code>:</p><div id="6d4c"><pre><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Test</span>, <span class="hljs-title class_">TestingModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/testing'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">INestApplication</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>; <span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> request <span class="hljs-keyword">from</span> <span class="hljs-string">'supertest'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">AppModule</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./../src/app.module'</span>;

<span class="hljs-title function_">describe</span>(<span class="hljs-string">'ItemController (e2e)'</span>, <span class="hljs-function">() =></span> { <span class="hljs-keyword">let</span> <span class="hljs-attr">app</span>: <span class="hljs-title class_">INestApplication</span>;

<span class="hljs-title function_">beforeAll</span>(<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> <span class="hljs-attr">moduleFixture</span>: <span class="hljs-title class_">TestingModule</span> = <span class="hljs-keyword">await</span> <span class="hljs-title class_">Test</span>.<span class="hljs-title function_">createTestingModule</span>({
        <span class="hljs-attr">imports</span>: [<span class="hljs-title class_">AppModule</span>],
    }).<span class="hljs-title function_">compile</span>();

    app = moduleFixture.<span class="hljs-title function_">createNestApplication</span>();
    <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">init</span>();
});

<span class="hljs-title function_">afterAll</span>(<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> app.<span class="hljs-title function_">close</span>();
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items (GET)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">get</span>(<span class="hljs-string">'/items'</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

<span class="hljs-keyword">let</span> <span class="hljs-attr">itemId</span>: <span class="hljs-built_in">string</span>;

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items (POST)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">post</span>(<span class="hljs-string">'/items'</span>)
        .<span class="hljs-title function_">send</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Sample Item'</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">'Sample Description'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">100</span> })
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">201</span>)
        .<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
            itemId = response.<span class="hljs-property">body</span>.<span class="hljs-property">_id</span>; <span class="hljs-comment">// Assuming the response contains the created item with its ID</span>
        });
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (GET)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">get</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {
            <span class="hljs-title function_">expect</span>(response.<span class="hljs-property">body</span>.<span class="hljs-property">name</span>).<span class="hljs-title function_">toEqual</span>(<span class="hljs-string">'Sample Item'</span>);
        });
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (PUT)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">put</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">send</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Updated Item'</span> })
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

<span class="hljs-title function_">it</span>(<span class="hljs-string">'/items/:id (DELETE)'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-title function_">request</span>(app.<span class="hljs-title function_">getHttpServer</span>())
        .<span class="hljs-title function_">delete</span>(<span class="hljs-string">`/items/<span class="hljs-subst">${itemId}</span>`</span>)
        .<span class="hljs-title function_">expect</span>(<span class="hljs-number">200</span>);
});

});

</pre></div><h1 id="53b2">Conclusion:</h1><p id="36d8">This is a basic setup to create a CRUD application using NestJS with MongoDB and then test it. You can expand this app by adding validation, error handling, and other features as needed. The combination of NestJS and MongoDB offers powerful capabilities, and testing ensures that your application behaves as expected.</p></article></body>

HAIKU

Lamentations of the Fruit Fly

I promised this to The Pub!

This one is enjoying life to the fullest right now / Photo by Erik_Karits on Pixabay.

The smell of rotten fruit

A life lived to the fullest for fifty days

The fruit flies fall silent

***

I hope you learned something because Grammarly thinks this Haiku sounds super informative!

Wow! So informative. / Screenshot by author

Join The Pub! They let you write about fruit flies!

Haiku
Poetry
Humor
Smillew Is Love
Fruit Flies
Recommended from ReadMedium