我已经使用使用 PUT 动词的WCF WebAPI组合了一个 HTTP 驱动的 API。当托管在 IIS Express 上的 MVC3 项目中时,一切都按设计工作。
但是,当我进行单元测试时,我偶尔会想要测试传输方面,而不仅仅是针对我自己的资源。我的单元测试失败,出现 405 - MethodNotAllowed。同样,在 IIS 中托管的服务完全相同(我在配置文件中启用了 PUT 和 DELETE 动词)。
我怎样才能让测试中使用的“自托管”服务也接受这些动词?
几乎相同的“get”测试有效,所以我不希望以下概念有问题......希望......
[Test]
public void PutNewMachine()
{
// Create new record to add
var machine = new Machine
{
ID = 1,
Name = "One",
Description = "Machine #1",
Location = 1
};
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(
HttpMethod.Put,
HOST + "/1"))
{
request.Content = new ObjectContent<Machine>(machine);
using (var response = client.Send(request))
{
Assert.AreEqual(
HttpStatusCode.Created,
response.StatusCode,
"New record put should have been acknowledged "
+ "with a status code of 'Created'");
}
}
}
}
在测试设置中,我正在使用以下 Autofac 代码准备端点(这同样适用于“Get”):
var builder = new ContainerBuilder();
builder
.Register(c => new FakeDatabase())
.As<IDatabase>()
.SingleInstance();
builder
.Register(c => new GenericRepository<Machine>(c.Resolve<IDatabase>()))
.As<IResourceRepository<Machine>>();
builder
.Register(c => new MachineService(c.Resolve<IResourceRepository<Machine>>()))
.As<MachineService>();
Container = builder.Build();
Scope = Container.BeginLifetimeScope();
host = new HttpServiceHost(typeof(MachineService), HOST);
host.AddDependencyInjectionBehavior<MachineService>(Container);
host.Open();
我的服务在以下接口中定义:
[ServiceContract]
public interface IResourceService<in TKey, TResource>
{
[WebGet(UriTemplate = "{key}")]
TResource Get(TKey key);
[WebInvoke(Method = "PUT", UriTemplate = "{key}")]
TResource Put(TKey key, TResource resource);
[WebInvoke(Method = "POST")]
TResource Post(TResource resource);
[WebInvoke(Method = "DELETE", UriTemplate = "{key}")]
void Delete(TKey key);
}
因此,例如,如果我有一个 MachineService,它会实现接口(两者class MachineService : IResourceService<string, Machine>
都已... : IResourceService<int, Machine>
经过试验 - Get = OK,Put = Nothing。
编辑:我似乎在 InternalServerError 和 MethodNotAllowed 错误之间弹跳 - 仅在使用自托管时。我已确保我作为用户有权打开端口(Win7 + 非管理员),但结果加上我选择的端口似乎对 Get 来说是可预测的功能。“邮政”似乎有类似的问题!:-(
EDIT2:界面现在已更改为哪个有效!
[ServiceContract]
public interface IResourceService<in TKey, TResource>
{
[WebGet(UriTemplate = "{key}")]
TResource Get(TKey key);
[WebInvoke(Method = "PUT", UriTemplate = "{key}")]
TResource Put(HttpRequestMessage<TResource> resourceRequest, TKey key);
[WebInvoke(Method = "POST", UriTemplate = "{key}")]
TResource Post(HttpRequestMessage<TResource> resourceRequest, TKey key);
[WebInvoke(Method = "DELETE", UriTemplate = "{key}")]
void Delete(TKey key);
}