我正在尝试为我的工作人员单元测试数据存储库。
存储库采用DatabaseContext实例访问mongodb数据库,并为工作人员公开IMongoCollection,如下所示。
我使用Moq来制作IMongoCollection和DatabaseContext的模拟。 在DatabaseContext的Moq设置中,我选择在调用公开的Workorder属性时返回IMongoCollection。反过来,当DeleteOneAsync时,模拟的IMongoCollection返回DeleteResult.Acknowledged(1)任务 被称为。
通过这种方式,我希望进行一些单元测试而不需要运行数据库,但是我遇到了一个错误,告诉我“System.NullReferenceException : Object reference not set to an instance of an object.
”,当我试图做“return result.DeleteCount == 1
时指向一行},其结果是返回的DeleteResult对象。
好像我的结果没有正确创建,下面是我的代码。
错误本身 在运行测试时发生
Test Name: MESAPITests.RepositoryTests.WorkorderRepositoryTests.DeleteWorkorderById_ReturnsBooleanTrue
Test FullName: MESAPITests.RepositoryTests.WorkorderRepositoryTests.DeleteWorkorderById_ReturnsBooleanTrue
Test Source: C:\Users\Zacke\Documents\Repositories\MES-API\MES-API Tests\RepositoryTests\WorkorderRepositoryTests.cs : line 22
Test Outcome: Failed
Test Duration: 0:00:00.354
Result StackTrace:
at MESAPI.Repositories.WorkorderRepository.<DeleteWorkorderById>d__2.MoveNext() in C:\Users\Zacke\Documents\Repositories\MES-API\MES-API\Repositories\WorkRepositories\WorkorderRepository.cs:line 28
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MESAPITests.RepositoryTests.WorkorderRepositoryTests.<DeleteWorkorderById_ReturnsBooleanTrue>d__1.MoveNext() in C:\Users\Zacke\Documents\Repositories\MES-API\MES-API Tests\RepositoryTests\WorkorderRepositoryTests.cs:line 34
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
DataRepositoryTests
public class WorkorderRepositoryTests
{
private WorkorderRepository _repo;
[Fact]
public async void DeleteWorkorderById_ReturnsBooleanTrue()
{
var mockCollection = new Mock<IMongoCollection<Workorder>>();
mockCollection
.Setup(_ => _.DeleteOneAsync(It.IsAny<Expression<Func<Workorder, bool>>>(),
default(CancellationToken)))
.ReturnsAsync(await Task.Run<DeleteResult>(() => new DeleteResult.Acknowledged(1)));
var mockContext = new Mock<IDatabaseContext>();
mockContext.Setup(_ => _.Workorders).Returns(mockCollection.Object);
_repo = new WorkorderRepository(mockContext.Object);
var id = ObjectId.GenerateNewId().ToString();
var result = await _repo.DeleteWorkorderById(id);
Assert.True(result);
}
}
WorkorderRepository DeleteWorkorderById
中的第二行发生错误public class WorkorderRepository : IWorkorderRepository
{
private readonly IMongoCollection<Workorder> _workorders;
public WorkorderRepository(IDatabaseContext context)
{
_workorders = context.Workorders;
}
public async Task<bool> DeleteWorkorderById(string id)
{
var result = await _workorders.DeleteOneAsync(w => w.Id == id);
return result.DeletedCount == 1;
}
public async Task<List<Workorder>> GetAllWorkordersAsList()
{
return await _workorders.FindAsync(new BsonDocument()).Result.ToListAsync();
}
public async Task<Workorder> GetWorkorderById(string id)
{
return await _workorders.FindAsync(w => w.Id == id).Result.FirstOrDefaultAsync();
}
public async Task<Workorder> PostNewWorkroder(WorkorderPost workorderPost)
{
var newWorkorder = new Workorder(workorderPost);
await _workorders.InsertOneAsync(newWorkorder);
return await _workorders.FindAsync(w => w.Id == newWorkorder.Id).Result.FirstOrDefaultAsync();
}
public async Task<bool> UpdateWorkorder(Workorder workorder)
{
var result = await _workorders.ReplaceOneAsync(w => w.Id == workorder.Id, workorder);
return result.MatchedCount != 0;
}
}
IDatabaseRepository
public interface IDatabaseContext
{
/// <summary>
/// Mongo database context.
/// </summary>
IMongoDatabase Database { get; set; }
/// <summary>
/// BomFamily database context.
/// </summary>
IMongoCollection<BomFamily> BomFamilies { get; set; }
/// <summary>
/// BomGroup database context.
/// </summary>
IMongoCollection<BomGroup> BomGroups { get; set; }
/// <summary>
/// BomItem database context.
/// </summary>
IMongoCollection<BomItem> BomItems { get; set; }
/// <summary>
/// Event database context.
/// </summary>
IMongoCollection<Event> Events { get; set; }
/// <summary>
/// EventAttribute database context.
/// </summary>
IMongoCollection<EventAttribute> EventAttributes { get; set; }
/// <summary>
/// EventType database context.
/// </summary>
IMongoCollection<EventType> EventTypes { get; set; }
/// <summary>
/// Job database context.
/// </summary>
IMongoCollection<Job> Jobs { get; set; }
/// <summary>
/// Product database context.
/// </summary>
IMongoCollection<Product> Products { get; set; }
/// <summary>
/// QualityEvent database context.
/// </summary>
IMongoCollection<QualityEvent> QualityEvents { get; set; }
/// <summary>
/// QualityTest database context.
/// </summary>
IMongoCollection<QualityTest> QualityTests { get; set; }
/// <summary>
/// QualityVariable database context.
/// </summary>
IMongoCollection<QualityVariable> QualityVariables { get; set; }
/// <summary>
/// Status database context.
/// </summary>
IMongoCollection<Status> Statuses { get; set; }
/// <summary>
/// StatusGroup database context.
/// </summary>
IMongoCollection<StatusGroup> StatusGroups { get; set; }
/// <summary>
/// User database context.
/// </summary>
IMongoCollection<User> Users { get; set; }
/// <summary>
/// WorkArea database context.
/// </summary>
IMongoCollection<WorkArea> WorkAreas { get; set; }
/// <summary>
/// WorkCell database context.
/// </summary>
IMongoCollection<WorkCell> WorkCells { get; set; }
/// <summary>
/// Workorder database context.
/// </summary>
IMongoCollection<Workorder> Workorders { get; set; }
}
在DeleteOneAsync上更改输入类型时出现新错误
到 It.IsAny<FilterDefinition<Workorder>>()
Test Name: MESAPITests.RepositoryTests.WorkorderRepositoryTests.DeleteWorkorderById_ReturnsBooleanTrue
Test FullName: MESAPITests.RepositoryTests.WorkorderRepositoryTests.DeleteWorkorderById_ReturnsBooleanTrue
Test Source: C:\Users\Zacke\Documents\Repositories\MES-API\MES-API Tests\RepositoryTests\WorkorderRepositoryTests.cs : line 21
Test Outcome: Failed
Test Duration: 0:00:00.283
Result StackTrace:
at MESAPI.Repositories.WorkorderRepository.<DeleteWorkorderById>d__2.MoveNext() in C:\Users\Zacke\Documents\Repositories\MES-API\MES-API\Repositories\WorkRepositories\WorkorderRepository.cs:line 28
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MESAPITests.RepositoryTests.WorkorderRepositoryTests.<DeleteWorkorderById_ReturnsBooleanTrue>d__1.MoveNext() in C:\Users\Zacke\Documents\Repositories\MES-API\MES-API Tests\RepositoryTests\WorkorderRepositoryTests.cs:line 33
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
Picture: Hovering over result in the line above tells me it's null for some reason..
答案 0 :(得分:1)
根据评论进行更新。 归功于StuartLC
Moq无法模拟扩展方法,应该直接在被模拟的接口成员上完成。
mockCollection
.Setup(_ => _.DeleteOneAsync(It.IsAny<FilterDefinition<Workorder>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DeleteResult.Acknowledged(1));