I’m trying to create xUnit using mock tests for my api that uses DataAccess layer for mongodb. But for some reason it just doesn’t parse okResult to Json or Bson. I definitely know that there is 2 values that I need from debugger: 
My model is:
namespace DataAccess.Models;
[BsonIgnoreExtraElements]
public class CyberGood
{
[BsonId]
[BsonElement("id")]
public ObjectId Id { get; set; }
[BsonElement("name")]
public string Name { get; set; }
[BsonElement("description")]
public string Description { get; set; }
[BsonElement("insideOf")]
public string? InsideOf { get; set; }
[BsonElement("madeIn")]
public string MadeIn { get; set; }
[BsonElement("price")]
public decimal Price { get; set; }
[BsonElement("amount")]
public int Amount { get; set; }
}
And my controller is:
[Route("api/[controller]")]
[ApiController]
public class CyberGoodController : ControllerBase
{
private readonly ICyberGoodService _cyberGoodService;
public CyberGoodController(ICyberGoodService cyberGoodService)
{
_cyberGoodService = cyberGoodService;
}
[HttpGet]
public async Task<IActionResult> GetAllCyberGoodAsync()
{
try
{
var cyberGoods = await _cyberGoodService.GetAllCyberGoodAsync();
return Ok(cyberGoods);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
My test case:
[Fact]
[Obsolete]
public async Task GetAll_CyberGoods_ReturnsList()
{
//Arrange
var mock = new Mock<ICyberGoodService>();
mock.Setup(d => d.GetAllCyberGoodAsync()).ReturnsAsync(GetTestCyberGoods());
var service = new CyberGoodController(mock.Object);
var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type)
|| type.FullName.StartsWith("DataAccess")
|| type.FullName.StartsWith("Microsoft.AspNetCore.Mvc.OkObjectResult"));
BsonSerializer.RegisterSerializer(objectSerializer);
//Act
IActionResult result = await service.GetAllCyberGoodAsync();
var bsonRes = BsonSerializer.Deserialize<List<CyberGood>>(result.ToBson());
//Assert
Assert.Equal(GetTestCyberGoods().Count, bsonRes.Count);
}
But instead of some test result it gives me this error:
Message:
MongoDB.Bson.BsonSerializationException : An error occurred while serializing the Value property of class Microsoft.AspNetCore.Mvc.ObjectResult: Type System.Collections.Generic.List1[[DataAccess.Models.CyberGood, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] is not configured as an allowed type for this instance of ObjectSerializer. ---- MongoDB.Bson.BsonSerializationException : Type System.Collections.Generic.List1[[DataAccess.Models.CyberGood, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] is not configured as an allowed type for this instance of ObjectSerializer.
Stack Trace:
BsonClassMapSerializer1.SerializeMember(BsonSerializationContext context, Object obj, BsonMemberMap memberMap) BsonClassMapSerializer1.SerializeClass(BsonSerializationContext context, BsonSerializationArgs args, TClass document)
BsonClassMapSerializer1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TClass value) IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value) ObjectSerializer.SerializeDiscriminatedValue(BsonSerializationContext context, BsonSerializationArgs args, Object value, Type actualType) ObjectSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value) DiscriminatedInterfaceSerializer1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TInterface value)
IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value)
BsonExtensionMethods.ToBson(Object obj, Type nominalType, BsonBinaryWriterSettings writerSettings, IBsonSerializer serializer, Action1 configurator, BsonSerializationArgs args) BsonExtensionMethods.ToBson[TNominalType](TNominalType obj, IBsonSerializer1 serializer, BsonBinaryWriterSettings writerSettings, Action1 configurator, BsonSerializationArgs args) CyberGoodControllerTests.GetAll_CyberGoods_ReturnsList() line 30 --- End of stack trace from previous location --- ----- Inner Stack Trace ----- ObjectSerializer.SerializeDiscriminatedValue(BsonSerializationContext context, BsonSerializationArgs args, Object value, Type actualType) ObjectSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value) IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, Object value) IBsonSerializerExtensions.Serialize(IBsonSerializer serializer, BsonSerializationContext context, Object value) BsonClassMapSerializer1.SerializeNormalMember(BsonSerializationContext context, Object obj, BsonMemberMap memberMap)
BsonClassMapSerializer`1.SerializeMember(BsonSerializationContext context, Object obj, BsonMemberMap memberMap)
>Solution :
Don’t think BsonSerializer can serialize/deserialize the value with IActionResult type.
Instead,
-
Cast
resultasOkObjectResulttype. And assert theokResultis not null to prove the action returns anOkObjectResult. -
Extract
okResult.Valueand cast it asList<CyberGood>type. And assert thebsonResis not null to prove that the value isList<CyberGood>type. -
Lastly, you are able to perform the assertion for matching the counts.
IActionResult result = await service.GetAllCyberGoodAsync();
var okResult = result as OkObjectResult();
// Validate result returned as OkResult
Assert.NotNull(okResult);
var bsonRes = okResult.Value as List<CyberGood>;
// Assert bsonRes is List<CyberGood> type
Assert.NotNull(bsonRes);
// Assert
Assert.Equal(GetTestCyberGoods().Count, bsonRes.Count);