首页 > 解决方案 > XUnit 模拟方法但不返回预期结果

问题描述

我在 XUnit 测试中使用 moq,但由于某种原因,模拟无法正常工作。这是我的单元测试:

 [Fact]
        public async Task SampleUnitTest()
        {
            //Arrange
            var httpClient = new HttpClient(new FakeHttpMessageHandler());
            _mockConstructRequest.Setup(x => x.ConstructRequestString(searchRequestModel))
                                 .Returns("a sample string");
            var service = new LibraryService(_mockConstructRequest.Object);

            //Act
            var response = service.GetResponse(new Request(), httpClient);

            //Assert
            response.Should().BeNull();

        }

         private class FakeHttpMessageHandler : HttpMessageHandler
        {
            public Func<HttpRequestMessage, CancellationToken, HttpResponseMessage> HttpRequestHandler { get; set; } =
            (r, c) =>
                new HttpResponseMessage
                {
                    ReasonPhrase = r.RequestUri.AbsoluteUri,
                    StatusCode = HttpStatusCode.OK
                };


            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                return Task.FromResult(HttpRequestHandler(request, cancellationToken));
            }
        } 

这是实际的代码,我正在尝试测试GetResponse方法。

  public class LibraryService : ILibraryService
 {
    private IConfiguration _configuration;
    private IRequestConstructor _requestContructor;
    public LibraryService (IRequestConstructor requestConstructor)
    {
        _requestConstructor = requestConstructor;
    }

    public async Task<Response> GetResponse(Request request, HttpClient client)
        {

            //construct request
            string requestString = _constructRequestString.ConstructRequestString(request, client);

            return null;
        }
 }

 public class RequestContructor : IRequestContructor
 {
  public string ConstructRequestString(Request request)
        {
            return "a request string";
        }
 }

我试图从我的单元测试中单步执行代码,但是当断点位于这一行时,requestString变量为空,而它应该返回“示例字符串”。有谁知道为什么?

string requestString = _constructRequestString.ConstructRequestString(request, client);

标签: c#moqxunit

解决方案


据我所见,您的模拟不正确:您的模拟:

_mockConstructRequest.Setup(x => x.ConstructRequestString(searchRequestModel))
                                 .Returns("a sample string");

您正在调用的方法:

_constructRequestString.ConstructRequestString(request, client);

不应该是这样的:

_mockConstructRequest.Setup(x => x.ConstructRequestString(It.IsAny<Request>(),It.IsAny<HttpClient>()))
                                 .Returns("a sample string");

最重要的是:

尝试在构造函数中而不是在每个测试中初始化你的模拟和你的“classUnderTest”,它会在每次测试前运行并为你做所有事情。例如:

public class UnitTestClass{

private readonly ClassUnderTest _classUnderTest;
private readonly Mock<ClassUnderTestDependecy> mockedInstance;

public UnitTestClass {
mockedInstance= new Mock<ClassUnderTestDependecy>();
_classUnderTest= new ClassUnderTest (ClassUnderTestDependecy.Object);
}

}

推荐阅读