我有webapi用于测试目的我在owin托管。我已经使用autofac进行了设置。现在,当我测试时,我想注入moq依赖项。到目前为止我无法做到这一点。我已阅读文档并进行了一些研究,但我遗漏了一些东西。
这是测试代码。
[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);
}
}
}
请看一下。让我知道我错过了什么。如果您想查看控制器代码或任何其他部分,请告诉我。
这是启动代码
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有使用最新注册的行为,所以它将在这里使用mocked。
答案 0 :(得分:4)
你快到了。
在测试中,您需要使用 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
}
}
}
答案 1 :(得分:0)
单元测试应测试单个组件。在您的情况下,您尝试通过HTTP查询测试AirportController
,而不是AirportController
作为独立组件。
AirportController
类取决于IAirportService
组件。为了在没有任何依赖性的情况下测试组件,您在IAirportService
上创建了一个moq。现在,您可以使用此moq实例化新的AirportController
并使用此实例运行测试。
如果你有AirportController
这样的话
public class AirportController
{
public AirportController(IAirportService airportService) { /* ... */}
}
AirportController
测试应该是这样的:
[Test]
public void Request_all_airports()
{
AirportCollection moqAirportCollection = new AirportCollection();
var moqAirPort = new Airport{ IATA = "moq",Name = "moqName" };
moqAirportCollection.Airports = new List<Airport>{ moqAirPort };
using (var mock = AutoMock.GetLoose())
{
var moqAirportService = mock.Mock<IAirportService>()
.Setup(x => x.GetAirports())
.Returns(moqAirportCollection);
var testedAirportController = new AirportController(moqAirportService);
AirportCollection airportCollection = testedAirportController.Get();
Assert.AreEquals(1, airportCollection.Length, "Invalid number of airport");
Assert.AreEquals(moqAirPort.Name, airportCollection[0].Name, "Invalid name");
}
}