using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
public class TagsController : ControllerBase
private readonly Demo1DbContext _context;
private readonly ITagsService tagsService;
public TagsController(Demo1DbContext context,
ITagsService tagsService)
this.tagsService = tagsService;
public async Task<ActionResult<ICollection<Tag>>> GetTags()
return Ok(await tagsService.GetTags());
public async Task<ActionResult<Tag>> GetTag(int id)
var Tag = await _context.Tags.FindAsync(id);
return Tag == null ? NotFound() : Ok(Tag);
public async Task<ActionResult<Tag>> CreateTag(Tag Tag)
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetTag), new { id = Tag.Id }, Tag);
public async Task<IActionResult> UpdateTag(int id, Tag Tag)
if (id != Tag.Id) return BadRequest();
_context.Entry(Tag).State = EntityState.Modified;
await _context.SaveChangesAsync();
public async Task<IActionResult> DeleteTag(int id)
var Tag = await _context.Tags.FindAsync(id);
if (Tag == null) return NotFound();
_context.Tags.Remove(Tag);
await _context.SaveChangesAsync();
public interface ITagsService
Task<Tag> CreateTag(Tag tag);
Task<Tag> UpdateTag(string TagId, Tag tag);
Task DeleteTag(string id);
Task<Tag?> GetTag(string tagId);
Task<ICollection<Tag>> GetTags();
Task<List<ExistResponse>> CheckNamesExist(List<string> names);
public class TagsService : ITagsService
private readonly Demo1DbContext _context;
public TagsService(Demo1DbContext context)
public async Task<Tag> CreateTag(Tag tag)
throw new NotImplementedException();
public async Task DeleteTag(string id)
throw new NotImplementedException();
public async Task<Tag?> GetTag(string tagId)
throw new NotImplementedException();
public async Task<ICollection<Tag>> GetTags()
return await _context.Tags.Select(t => new Tag
public async Task<List<ExistResponse>> CheckNamesExist(List<string> names)
throw new NotImplementedException();
public async Task<Tag> UpdateTag(string tagId, Tag tag)
throw new NotImplementedException();
public int? Id { get; set; }
public string? Name { get; set; }
public bool IsUsed { get; set; }
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
public class ExistResponse
public string Name { get; set; } = string.Empty;
public bool Exists { get; set; } = false;
public class Demo1DbContext : DbContext
public Demo1DbContext(DbContextOptions<Demo1DbContext> options)
public DbSet<Tag> Tags { get; set; } = null!;
public class TagsControllerTests
private DbContextOptions<Demo1DbContext> _options;
private Demo1DbContext _context;
private ITagsService _mockTagsService;
private TagsController _tagsController;
_options = new DbContextOptionsBuilder<Demo1DbContext>()
.UseInMemoryDatabase(databaseName: "test_database")
_context = new Demo1DbContext(_options);
_context.Database.EnsureDeleted();
_context.Database.EnsureCreated();
_context.Tags.AddRange(new[]
new Tag { Id = 1, Name = "Tag1" },
new Tag { Id = 2, Name = "Tag2" },
new Tag { Id = 3, Name = "Tag3" }
_mockTagsService = Substitute.For<ITagsService>();
_tagsController = new TagsController(_context, _mockTagsService);
public async Task Teardown()
await _context.DisposeAsync();
public async Task GetTags_Valid_ReturnTag()
var expectedTagResponse = new Tag
_mockTagsService.GetTags().Returns(new List<Tag> { expectedTagResponse });
var tagsResult = await _tagsController.GetTags();
var tagsResultObject = tagsResult.Result as ObjectResult;
Assert.That(tagsResultObject, Is.Not.Null);
ICollection<Tag>? tags = tagsResultObject.Value as ICollection<Tag>;
Assert.That(tags, Is.Not.Null);
var tagsList = tags.ToList();
Assert.That(tags, Is.Not.Null);
Assert.That(tags, Has.Count.EqualTo(1));
Assert.That(tagsList[0].Id, Is.EqualTo(1));
Assert.That(tagsList[0].Name, Is.EqualTo("tag-name-1"));
Assert.That(tagsList[0].IsUsed, Is.EqualTo(true));
public class TagServiceTests
private DbContextOptions<Demo1DbContext> _options;
private Demo1DbContext _context;
private TagsService _tagsService;
_options = new DbContextOptionsBuilder<Demo1DbContext>()
.UseInMemoryDatabase(databaseName: "test_database")
_context = new Demo1DbContext(_options);
_context.Database.EnsureDeleted();
_context.Database.EnsureCreated();
_context.Tags.AddRange(new[]
new Tag { Id = 1, Name = "Tag1" },
new Tag { Id = 2, Name = "Tag2" },
new Tag { Id = 3, Name = "Tag3" }
_tagsService = new TagsService(_context);
public async Task Teardown()
await _context.DisposeAsync();
public async Task GetTags_ReturnsMatchingTags()
var result = (await _tagsService.GetTags()).ToList();
Assert.That(result, Has.Count.EqualTo(3));
public async Task GeneralTagTest_ReturnsMatchingTags()
var result = (await _tagsService.GetTags()).ToList();
Assert.That(result, Has.Count.EqualTo(3));
public static void Main()
var x = new NUnitLite.AutoRun().Execute(new string[]{"--test:LS.TagsControllerTests", "--noc"});
Console.WriteLine("----------------------------------------------");
Console.WriteLine("TagsControllerTests");
Console.WriteLine(x==0?"All Test Passed... :¬)": string.Format("{0} tests failed... :¬(", x));
Console.WriteLine("----------------------------------------------");
var y = new NUnitLite.AutoRun().Execute(new string[]{"--test:LS.TagServiceTests", "--noc"});
Console.WriteLine("TagsServiceTests");
Console.WriteLine("----------------------------------------------");
Console.WriteLine(y==0?"All Test Passed... :¬)": string.Format("{0} tests failed... :¬(", y));
Console.WriteLine("----------------------------------------------");
-Use NSubstitute to mock ITagsService and verify error handling in TagsController (TagsControllerTests with Mock Approach) similiar to the existing test 'TagsControllerTests.GetTags_Valid_ReturnTag'