Skip to main content
 首页 » 编程设计

c#之Owin 托管的 webapi 2.2。使用模拟服务测试 Controller

2024年02月05日37haluo1

我有 webapi,出于测试目的,我将其托管在 owin 中。我已经使用 autofac 进行了设置。现在,当我进行测试时,我想注入(inject)最小起订量依赖项。到目前为止我还做不到。我已经阅读了文档并做了一些研究,但我遗漏了一些东西。

这是测试代码。

 [Test] 
    public void Request_all_airports() 
    { 
        const int port = 8086; 
        AirportCollection moqAirportCollection = new AirportCollection(); 
        moqAirportCollection.Airports = new List<Airport>{new Airport{IATA = "moq",Name = "moqName"}}; 
 
        using (WebApp.Start<Startup>("http://localhost:" + port)) 
        { 
            using (var mock = AutoMock.GetLoose()) 
            { 
                var moqObj =  mock.Mock<IAirportService>().Setup(x => x.GetAirports()).Returns(moqAirportCollection); 
 
                var client = new HttpClient {BaseAddress = new Uri("http://localhost:" + port)}; 
                var response = client.GetAsync("/api/airport/get").Result; 
                var body = response.Content.ReadAsStringAsync().Result; 
                var airportCollection = JsonConvert.DeserializeObject<AirportCollection>(body); 
            } 
        } 
    } 

请看。让我知道我错过了什么。如果您想查看 Controller 代码或任何其他代码,请告诉我。

这是启动代码

 public class Startup 
{ 
    public static IContainer container { get; set; } 
 
    public void Configuration(IAppBuilder appBuilder) 
    { 
        var httpConfig = new HttpConfiguration(); 
        container = AutofacSetup.Register(httpConfig); 
        WebApiConfig.Register(httpConfig); 
 
 
        appBuilder.UseAutofacMiddleware(container); 
        appBuilder.UseAutofacWebApi(httpConfig); 
        appBuilder.UseWebApi(httpConfig); 
    } 
} 

谢谢

我是这么认为的,我已经在人们的帮助下解决了它。这是我的代码。

var moq = new Mock<IAirportService>(); 
                moq.Setup(x => x.GetAirports()).Returns(moqAirportCollection); 
                newBuilder.RegisterInstance(moq.Object).As<IAirportService>(); 
                newBuilder.Update(Startup.container); 

我还没有重建我刚刚更新的约束。 autofac 具有使用最新注册的行为,因此它将在此处使用模拟。

请您参考如下方法:

你快到了。

在您的测试中,您需要使用您的 autofac 容器注册您的模拟服务,以便通过应用程序中的模拟解决对 IAirportService 的依赖。

实现此目的的一种方法是为每个测试覆盖Startup 类的Configuration 方法,并将您的测试DI 放在那里。我在下面添加了一些评论以显示可以进行的更改:

public class Startup 
{ 
    public static IContainer container { get; set; } 
 
    // make this virtual 
    public virtual void Configuration(IAppBuilder appBuilder) 
    { 
        var httpConfig = new HttpConfiguration(); 
 
        // have this return the ContainerBuilder instead of the container 
        var builder = AutofacSetup.Register(httpConfig) 
        container = builder.Build(); 
 
        WebApiConfig.Register(httpConfig); 
 
 
        appBuilder.UseAutofacMiddleware(container); 
        appBuilder.UseAutofacWebApi(httpConfig); 
        appBuilder.UseWebApi(httpConfig); 
    } 
} 

然后在您的测试类中,派生自 Startup 类并将您的测试逻辑放入其中。像这样:

public class MyTestCase { 
        public static Mock<IAirportService> MockObj { get; set; } 
 
        private class TestStartup : Startup { 
            public override void Configuration(IAppBuilder app) { 
                var httpConfig = new HttpConfiguration(); 
 
                // this now returns ContainerBuilder instead of the container 
                var builder = AutofacSetup.Register(httpConfig) 
 
                // register your mock, change this to whatever lifetime scope you need 
                var moqAirportCollection = new AirportCollection(); 
                moqAirportCollection.Airports = new List<Airport>{new Airport{IATA = "moq",Name = "moqName"}}; 
                var mock = AutoMock.GetLoose() 
                MockObj = mock.Mock<IAirportService>() 
                                           .Setup(x => x.GetAirports()) 
                                           .Returns(moqAirportCollection); 
                var moqObj = MockObj.Object; 
                builder.RegisterInstance(moqObj).As<IAirportService>(); 
 
 
 
                container = builder.Build(); 
 
                WebApiConfig.Register(httpConfig); 
 
 
                appBuilder.UseAutofacMiddleware(container); 
                appBuilder.UseAutofacWebApi(httpConfig); 
                appBuilder.UseWebApi(httpConfig); 
            } 
        } 
 
        [Test] 
        public void Request_all_airports() 
        {     
           using (var server = WebApp.Start<Startup>()) 
           { 
               var response =  
                   server.CreateRequest("/api/airport/get") 
                         .GetAsync() 
                         .Result; 
 
                var body = response.Content.ReadAsStringAsync().Result; 
                var result = JsonConvert.DeserializeObject<AirportCollection>(body); 
 
                // assert something 
            } 
        } 
    }