Tôi đang cố gắng khám phá cách áp dụng async và chờ từ khóa cho các bài kiểm tra xUnit của mình. Tôi đang sử dụng xUnit 1.9 và Async CTP 1.3. Đây là trường hợp thử nghiệm của tôixUnit và Moq không hỗ trợ async - đang chờ từ khóa
Tôi có một giao diện mà chỉ gọi một phương pháp không đồng bộ
public interface IDoStuffAsync
{
Task AnAsyncMethod(string value);
}
Tôi có một lớp học mà tiêu thụ giao diện và gọi phương thức async
public class UseAnAsyncThing
{
private readonly IDoStuffAsync _doStuffAsync;
public UseAnAsyncThing(IDoStuffAsync doStuffAsync)
{
_doStuffAsync = doStuffAsync;
}
public async Task DoThatAsyncOperation(string theValue)
{
await _doStuffAsync.AnAsyncMethod(theValue);
}
}
Trong các thử nghiệm của tôi, tôi muốn kiểm tra xem phương thức DoThatAsyncOperation
có đang gọi phương thức có giá trị chính xác không vì vậy tôi giả lập giao diện và sử dụng Moq để xác minh cuộc gọi
[Fact]
public async void The_test_will_pass_even_though_it_should_fail()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));
await sut.DoThatAsyncOperation("test");
// This won't throw a Moq.MockExcpetion so the test appears to pass
// However it does not run
mock.Verify(x => x.AnAsyncMethod("fail"));
}
Thử nghiệm này đang sử dụng các từ khóa async
và await
. Khi nó chạy nó sai đi như Moq nên khẳng định rằng xác minh không thành công. Bất kỳ mã nào sau khi gọi tới số sut.DoThatAsyncOperation("test");
không chạy được
[Fact]
public void This_will_work_and_assert_the_reslt()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));
sut.DoThatAsyncOperation("test").ContinueWith(y => { });
// This won't throw a Moq.MockExcpetion so the test appears to pass
// However it does not run
mock.Verify(x => x.AnAsyncMethod("fail"));
}
Thử nghiệm này được thiết lập mà không phải chờ đợi và từ khóa không đồng bộ và chuyển tiền phạt.
Đây có phải là hành vi mong đợi đối với xUnit và Moq không?
Cập nhật
Cám ơn lời nhận xét của Stephen tôi quản lý để sửa chữa các thử nghiệm đầu tiên bằng cách làm cho hai thay đổi. Thử nghiệm hiện trả về một nhiệm vụ thay vì void và Mock cũng trả về một nhiệm vụ.
[Fact]
public async Task The_test_will_pass_even_though_it_should_fail()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())).ReturnAsync(true);
await sut.DoThatAsyncOperation("test");
// This now fails as it should
mock.Verify(x => x.AnAsyncMethod("fail"));
}
Thanks for Update đoạn trên. Các TaskCompletionSource là chìa khóa tôi đã được tìm kiếm trong mocking phương pháp async của tôi bằng cách sử dụng MOQ. –
Philippe
Thay vì tạo một TaskCompletionSource rõ ràng, bạn có thể chỉ cần sử dụng Task.FromResult: 'mock.Setup (x => x.AnAsyncMethod (It.IsAny())). Returns (Task.FromResult (true));' –
sapphiremirage
Bạn cũng có thể sử dụng mock.Setup (x => x.AnAsyncMethod (It.IsAny())). ReturnAsync (true); để tránh thiết lập nhiệm vụ –