public void ModelStatePropertyGetterWorks() { // Arrange ApiController controller = new Mock <ApiController>().Object; // Act ModelStateDictionary expected = new ModelStateDictionary(); expected.Add("a", new ModelState() { Value = new ValueProviders.ValueProviderResult("result", "attempted", CultureInfo.InvariantCulture) }); controller.ModelState.Add("a", new ModelState() { Value = new ValueProviders.ValueProviderResult("result", "attempted", CultureInfo.InvariantCulture) }); // Assert Assert.Equal(expected.Count, controller.ModelState.Count); }
public void Initialize_Default_Initializer_Can_Be_Removed() { // Arrange var config = new HttpConfiguration(); config.Initializer = (c) => { }; bool initializeCalled = false; Mock <ITraceManager> mock = new Mock <ITraceManager>() { CallBase = true }; mock.Setup(m => m.Initialize(config)).Callback(() => initializeCalled = true); config.Services.Replace(typeof(ITraceManager), mock.Object); // Act config.Initializer(config); // Assert Assert.False(initializeCalled); }
public void ReadFromStreamAsync_RoundTripsWriteToStreamAsync(Type variationType, object testData) { TestJsonMediaTypeFormatter formatter = new TestJsonMediaTypeFormatter(); HttpContent content = new StringContent(String.Empty); HttpContentHeaders contentHeaders = content.Headers; bool canSerialize = IsTypeSerializableWithJsonSerializer(variationType, testData) && Assert.Http.CanRoundTrip(variationType); if (canSerialize) { object readObj = null; Assert.Stream.WriteAndRead( stream => { Assert.Task.Succeeds(formatter.WriteToStreamAsync(variationType, testData, stream, content, transportContext: null)); contentHeaders.ContentLength = stream.Length; }, stream => readObj = Assert.Task.SucceedsWithResult(formatter.ReadFromStreamAsync(variationType, stream, content, null))); Assert.Equal(testData, readObj); } }
public void HttpSelfHostConfiguration_UserNamePasswordValidator_PropagatesToBinding(string address, HttpBindingSecurityMode mode) { // Arrange HttpBinding binding = new HttpBinding(); UserNamePasswordValidator validator = new Mock <UserNamePasswordValidator>().Object; HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address) { UserNamePasswordValidator = validator }; // Act BindingParameterCollection parameters = config.ConfigureBinding(binding); // Assert Assert.NotNull(parameters); ServiceCredentials serviceCredentials = parameters.Find <ServiceCredentials>(); Assert.NotNull(serviceCredentials); Assert.Equal(HttpClientCredentialType.Basic, binding.Security.Transport.ClientCredentialType); Assert.Equal(mode, binding.Security.Mode); }
public void InvokeActionWithExceptionFilters_IfActionTaskIsCanceled_ReturnsCanceledTask() { // Arrange List <string> log = new List <string>(); var actionTask = TaskHelpers.Canceled <HttpResponseMessage>(); var exceptionFilterMock = CreateExceptionFilterMock((ec, ct) => { log.Add("exceptionFilter"); return(Task.Factory.StartNew(() => { })); }); var filters = new[] { exceptionFilterMock.Object }; // Act var result = ApiController.InvokeActionWithExceptionFilters(actionTask, _actionContextInstance, CancellationToken.None, filters); // Assert Assert.NotNull(result); result.WaitUntilCompleted(); Assert.Equal(TaskStatus.Canceled, result.Status); Assert.Equal(new string[] { }, log.ToArray()); }
public void RequestLineParserAcceptsCustomMethods() { foreach (HttpMethod method in HttpUnitTestDataSets.CustomHttpMethods) { byte[] data = CreateBuffer(method.ToString(), "/", "HTTP/1.1"); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); HttpRequestLineParser parser = new HttpRequestLineParser(requestLine, data.Length); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(requestLine, method.ToString(), "/", new Version("1.1")); } } }
public Task ReadFromStreamAsync_WhenContentLengthIsZero_DoesNotCloseStream() { // Arrange TFormatter formatter = new TFormatter(); Mock <Stream> mockStream = new Mock <Stream>(); IFormatterLogger mockFormatterLogger = new Mock <IFormatterLogger>().Object; HttpContent content = new StringContent(String.Empty); HttpContentHeaders contentHeaders = content.Headers; contentHeaders.ContentLength = 0; // Act return(formatter.ReadFromStreamAsync(typeof(object), mockStream.Object, content, mockFormatterLogger). ContinueWith( readTask => { // Assert Assert.Equal(TaskStatus.RanToCompletion, readTask.Status); mockStream.Verify(s => s.Close(), Times.Never()); })); }
public void MultipartParserSingleShortBodyPart(string boundary) { byte[] data = CreateBuffer(boundary, "A"); for (var cnt = 1; cnt <= data.Length; cnt++) { MimeMultipartParser parser = CreateMimeMultipartParser(data.Length, boundary); Assert.NotNull(parser); int totalBytesConsumed; List <string> bodyParts; MimeMultipartParser.State state = ParseBufferInSteps(parser, data, cnt, out bodyParts, out totalBytesConsumed); Assert.Equal(MimeMultipartParser.State.BodyPartCompleted, state); Assert.Equal(data.Length, totalBytesConsumed); Assert.Equal(2, bodyParts.Count); Assert.Equal(0, bodyParts[0].Length); Assert.Equal(1, bodyParts[1].Length); Assert.Equal("A", bodyParts[1]); } }
public Task ReadFromStreamAsync_WhenContentLengthIsNull_ReadsDataButDoesNotCloseStream() { // Arrange TFormatter formatter = new TFormatter(); MemoryStream memStream = new MemoryStream(ExpectedSampleTypeByteRepresentation); HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders(); contentHeaders.ContentLength = null; // Act return(formatter.ReadFromStreamAsync(typeof(SampleType), memStream, contentHeaders, null).ContinueWith( readTask => { // Assert Assert.Equal(TaskStatus.RanToCompletion, readTask.Status); Assert.True(memStream.CanRead); var value = Assert.IsType <SampleType>(readTask.Result); Assert.Equal(42, value.Number); })); }
public void ValidationErrorsNotAddedOnInvalidFields() { // Arrange ModelMetadataProvider metadataProvider = new DataAnnotationsModelMetadataProvider(); HttpActionContext actionContext = ContextUtil.CreateActionContext(); object model = new Address() { Street = "Microsoft Way" }; actionContext.ModelState.AddModelError("Street", "error"); // Act new DefaultBodyModelValidator().Validate(model, typeof(Address), metadataProvider, actionContext, string.Empty); // Assert Assert.Contains("Street", actionContext.ModelState.Keys); ModelState streetState = actionContext.ModelState["Street"]; Assert.Equal(1, streetState.Errors.Count); }
public void StatusLineParserAcceptsCustomStatusCodes() { foreach (HttpStatusCode status in HttpUnitTestDataSets.CustomHttpStatusCodes) { byte[] data = CreateBuffer("HTTP/1.1", ((int)status).ToString(), "Reason"); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedResponse statusLine = new HttpUnsortedResponse(); HttpStatusLineParser parser = new HttpStatusLineParser(statusLine, data.Length); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(statusLine, new Version("1.1"), status, "Reason"); } } }
public Task <HttpResponseMessage> DisposedReturnsServiceUnavailable() { // Arrange Mock <HttpControllerDispatcher> dispatcherMock = new Mock <HttpControllerDispatcher>(); HttpServer server = new HttpServer(dispatcherMock.Object); HttpMessageInvoker invoker = new HttpMessageInvoker(server); server.Dispose(); HttpRequestMessage request = new HttpRequestMessage(); // Act return(invoker.SendAsync(request, CancellationToken.None).ContinueWith( (reqTask) => { // Assert dispatcherMock.Protected().Verify <Task <HttpResponseMessage> >("SendAsync", Times.Never(), request, CancellationToken.None); Assert.Equal(HttpStatusCode.ServiceUnavailable, reqTask.Result.StatusCode); return reqTask.Result; } )); }
public void HeaderParserSplitHeader() { byte[] data = InternetMessageFormatHeaderParserTests.CreateBuffer("N:V1,", " V2,", "\tV3,", " V4,", " \tV5"); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpHeaders headers; InternetMessageFormatHeaderParser parser = InternetMessageFormatHeaderParserTests.CreateHeaderParser(data.Length, out headers); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = InternetMessageFormatHeaderParserTests.ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); Assert.Equal(1, headers.Count()); IEnumerable <string> parsedValues = headers.GetValues("N"); Assert.Equal(1, parsedValues.Count()); Assert.Equal("V1, V2, V3, V4, \tV5", parsedValues.ElementAt(0)); } }
private static void ValidateResult( HttpUnsortedRequest requestLine, string method, string requestUri, Version version, Dictionary <string, string> headers) { Assert.Equal(new HttpMethod(method), requestLine.Method); Assert.Equal(requestUri, requestLine.RequestUri); Assert.Equal(version, requestLine.Version); if (headers != null) { Assert.Equal(headers.Count, requestLine.HttpHeaders.Count()); foreach (var header in headers) { Assert.True(requestLine.HttpHeaders.Contains(header.Key), "Parsed header did not contain expected key " + header.Key); Assert.Equal(header.Value, requestLine.HttpHeaders.GetValues(header.Key).ElementAt(0)); } } }
public void CookieHeaderValueClone() { // Arrange NameValueCollection nvc = new NameValueCollection(); nvc.Add("name", "value"); CookieHeaderValue expectedValue = new CookieHeaderValue("cookie", nvc); expectedValue.Domain = "domain"; expectedValue.Expires = DateTimeOffset.Now; expectedValue.MaxAge = TimeSpan.FromDays(10); expectedValue.Path = "path"; expectedValue.HttpOnly = true; expectedValue.Secure = true; // Act CookieHeaderValue actualValue = expectedValue.Clone() as CookieHeaderValue; // Assert Assert.Equal(expectedValue.ToString(), actualValue.ToString()); }
private static void ValidateResult( HttpUnsortedResponse statusLine, Version version, HttpStatusCode statusCode, string reasonPhrase, Dictionary <string, string> headers) { Assert.Equal(version, statusLine.Version); Assert.Equal(statusCode, statusLine.StatusCode); Assert.Equal(reasonPhrase, statusLine.ReasonPhrase); if (headers != null) { Assert.Equal(headers.Count, statusLine.HttpHeaders.Count()); foreach (var header in headers) { Assert.True(statusLine.HttpHeaders.Contains(header.Key), "Parsed header did not contain expected key " + header.Key); Assert.Equal(header.Value, statusLine.HttpHeaders.GetValues(header.Key).ElementAt(0)); } } }
public void FindKeysWithPrefixRecognizesRootChilden() { // Arrange IDictionary <string, int> dict = new Dictionary <string, int>() { { "[0]", 1 }, { "Name", 2 }, { "Address.Street", 3 }, { "", 4 } }; // Act List <int> results = DictionaryExtensions.FindKeysWithPrefix <int>(dict, "").Select(kvp => kvp.Value).ToList(); // Assert Assert.Equal(4, results.Count); Assert.Contains(1, results); Assert.Contains(2, results); Assert.Contains(3, results); Assert.Contains(4, results); }
public void FindReader_ReturnsNullOnNoMatch() { // Arrange MockMediaTypeFormatter formatter = new MockMediaTypeFormatter() { CallBase = true }; MediaTypeFormatterCollection collection = new MediaTypeFormatterCollection(); collection.Clear(); collection.Add(formatter); MediaTypeHeaderValue contentType = new MediaTypeHeaderValue("text/test"); // Act MediaTypeFormatter actualFormatter = collection.FindReader(typeof(object), contentType); // Assert Assert.Null(actualFormatter); }
public void ReadAsHttpResponseMessageVerifyArguments() { Assert.ThrowsArgumentNull(() => HttpContentMessageExtensions.ReadAsHttpResponseMessageAsync(null), "content"); Assert.ThrowsArgument(() => new ByteArrayContent(new byte[] { }).ReadAsHttpResponseMessageAsync(), "content"); Assert.ThrowsArgument(() => new StringContent(String.Empty).ReadAsHttpResponseMessageAsync(), "content"); Assert.ThrowsArgument(() => new StringContent(String.Empty, Encoding.UTF8, "application/http").ReadAsHttpResponseMessageAsync(), "content"); Assert.ThrowsArgument(() => { HttpContent content = new StringContent(String.Empty); content.Headers.ContentType = ParserData.HttpRequestMediaType; content.ReadAsHttpResponseMessageAsync(); }, "content"); Assert.ThrowsArgumentGreaterThanOrEqualTo(() => { HttpContent content = new StringContent(String.Empty); content.Headers.ContentType = ParserData.HttpResponseMediaType; content.ReadAsHttpResponseMessageAsync(ParserData.MinBufferSize - 1); }, "bufferSize", ParserData.MinBufferSize.ToString(), ParserData.MinBufferSize - 1); }
public void MultipleValidationErrorsOnSameMemberReported() { // Arrange ModelMetadataProvider metadataProvider = new DataAnnotationsModelMetadataProvider(); HttpActionContext actionContext = ContextUtil.CreateActionContext(); object model = new Address() { Street = "Microsoft Way" }; // Act Assert.DoesNotThrow(() => new DefaultBodyModelValidator().Validate(model, typeof(Address), metadataProvider, actionContext, string.Empty) ); // Assert Assert.Contains("Street", actionContext.ModelState.Keys); ModelState streetState = actionContext.ModelState["Street"]; Assert.Equal(2, streetState.Errors.Count); }
public void GetStream() { Stream stream0 = null; Stream stream1 = null; try { string tempPath = Path.GetTempPath(); MultipartFormDataContent content = new MultipartFormDataContent(); content.Add(new StringContent("Content 1"), "NoFile"); content.Add(new StringContent("Content 2"), "File", "Filename"); MultipartFileStreamProvider provider = new MultipartFileStreamProvider(tempPath); stream0 = provider.GetStream(content, content.ElementAt(0).Headers); stream1 = provider.GetStream(content, content.ElementAt(1).Headers); Assert.IsType <FileStream>(stream0); Assert.IsType <FileStream>(stream1); Assert.Equal(2, provider.FileData.Count); string partialFileName = String.Format("{0}BodyPart_", tempPath); Assert.Contains(partialFileName, provider.FileData[0].LocalFileName); Assert.Contains(partialFileName, provider.FileData[1].LocalFileName); Assert.Same(content.ElementAt(0).Headers.ContentDisposition, provider.FileData[0].Headers.ContentDisposition); Assert.Same(content.ElementAt(1).Headers.ContentDisposition, provider.FileData[1].Headers.ContentDisposition); } finally { if (stream0 != null) { stream0.Close(); } if (stream1 != null) { stream1.Close(); } } }
public void EqualsReturnsTrueIfMediaType1IsSubset() { string[] parameters = new string[] { ";name=value", ";q=1.0", ";version=1", }; MediaTypeHeaderValueEqualityComparer comparer = MediaTypeHeaderValueEqualityComparer.EqualityComparer; MediaTypeHeaderValue mediaType1 = new MediaTypeHeaderValue("text/*"); mediaType1.CharSet = "someCharset"; MediaTypeHeaderValue mediaType2 = new MediaTypeHeaderValue("TEXT/*"); mediaType2.CharSet = "SOMECHARSET"; Assert.Equal(mediaType1, mediaType2, comparer); mediaType1 = new MediaTypeHeaderValue("application/*"); mediaType1.CharSet = ""; mediaType2 = new MediaTypeHeaderValue("application/*"); mediaType2.CharSet = null; Assert.Equal(mediaType1, mediaType2, comparer); foreach (string parameter in parameters) { mediaType1 = new MediaTypeHeaderValue("text/xml"); mediaType2 = MediaTypeHeaderValue.Parse("TEXT/xml" + parameter); Assert.Equal(mediaType1, mediaType2, comparer); mediaType1 = new MediaTypeHeaderValue("text/*"); mediaType2 = MediaTypeHeaderValue.Parse("TEXT/*" + parameter); Assert.Equal(mediaType1, mediaType2, comparer); mediaType1 = new MediaTypeHeaderValue("*/*"); mediaType2 = MediaTypeHeaderValue.Parse("*/*" + parameter); Assert.Equal(mediaType1, mediaType2, comparer); } }
public void ReadFromStreamAsync_RoundTripsWriteToStreamAsyncUsingXmlSerializer(Type variationType, object testData) { TestXmlMediaTypeFormatter formatter = new TestXmlMediaTypeFormatter(); HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders(); bool canSerialize = IsSerializableWithXmlSerializer(variationType, testData) && Assert.Http.CanRoundTrip(variationType); if (canSerialize) { formatter.SetSerializer(variationType, new XmlSerializer(variationType)); object readObj = null; Assert.Stream.WriteAndRead( stream => { Assert.Task.Succeeds(formatter.WriteToStreamAsync(variationType, testData, stream, contentHeaders, transportContext: null)); contentHeaders.ContentLength = stream.Length; }, stream => readObj = Assert.Task.SucceedsWithResult(formatter.ReadFromStreamAsync(variationType, stream, contentHeaders, null))); Assert.Equal(testData, readObj); } }
public void Route_ActionName() { // Arrange ApiController api = new UsersRpcController(); HttpRouteData route = new HttpRouteData(new HttpRoute()); route.Values.Add("action", "Admin"); HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(instance: api, routeData: route, request: new HttpRequestMessage() { Method = HttpMethod.Post }); controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "test", typeof(UsersRpcController)); // Act HttpResponseMessage message = api.ExecuteAsync(controllerContext, CancellationToken.None).Result; User user = message.Content.ReadAsAsync <User>().Result; // Assert Assert.Equal("Yao", user.FirstName); Assert.Equal("Huang", user.LastName); }
public void InvokeActionWithAuthorizationFilters_ChainsFiltersInOrderFollowedByInnerActionContinuation() { // Arrange List <string> log = new List <string>(); Mock <IAuthorizationFilter> globalFilterMock = CreateAuthorizationFilterMock((ctx, ct, continuation) => { log.Add("globalFilter"); return(continuation()); }); Mock <IAuthorizationFilter> actionFilterMock = CreateAuthorizationFilterMock((ctx, ct, continuation) => { log.Add("actionFilter"); return(continuation()); }); Func <Task <HttpResponseMessage> > innerAction = () => Task <HttpResponseMessage> .Factory.StartNew(() => { log.Add("innerAction"); return(null); }); List <IAuthorizationFilter> filters = new List <IAuthorizationFilter>() { globalFilterMock.Object, actionFilterMock.Object, }; // Act var result = ApiController.InvokeActionWithAuthorizationFilters(_actionContextInstance, CancellationToken.None, filters, innerAction); // Assert Assert.NotNull(result); var resultTask = result(); Assert.NotNull(resultTask); resultTask.WaitUntilCompleted(); Assert.Equal(new[] { "globalFilter", "actionFilter", "innerAction" }, log.ToArray()); globalFilterMock.Verify(); actionFilterMock.Verify(); }
public Task ReadFromStreamAsync_WhenContentLengthIsZero_DoesNotReadStream() { // Arrange TFormatter formatter = new TFormatter(); Mock <Stream> mockStream = new Mock <Stream>(); IFormatterLogger mockFormatterLogger = new Mock <IFormatterLogger>().Object; HttpContentHeaders contentHeaders = FormattingUtilities.CreateEmptyContentHeaders(); contentHeaders.ContentLength = 0; // Act return(formatter.ReadFromStreamAsync(typeof(object), mockStream.Object, contentHeaders, mockFormatterLogger). ContinueWith( readTask => { // Assert Assert.Equal(TaskStatus.RanToCompletion, readTask.Status); mockStream.Verify(s => s.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()), Times.Never()); mockStream.Verify(s => s.ReadByte(), Times.Never()); mockStream.Verify(s => s.BeginRead(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <AsyncCallback>(), It.IsAny <object>()), Times.Never()); })); }
private static void ValidateContents(IEnumerable <HttpContent> contents) { int cnt = 0; foreach (var content in contents) { Assert.NotNull(content); Assert.NotNull(content.Headers); Assert.Equal(4, content.Headers.Count()); IEnumerable <string> parsedValues = content.Headers.GetValues(String.Format("N{0}", cnt)); Assert.Equal(1, parsedValues.Count()); Assert.Equal(String.Format("V{0}", cnt), parsedValues.ElementAt(0)); Assert.Equal(DefaultContentType, content.Headers.ContentType.MediaType); Assert.Equal(DefaultContentDisposition, content.Headers.ContentDisposition.DispositionType); Assert.Equal(String.Format("\"N{0}\"", cnt), content.Headers.ContentDisposition.FileName); cnt++; } }
public void ReadAsMultipartAsyncNestedMultipartContentAsync(string boundary) { const int nesting = 10; const string innerText = "Content"; MultipartContent innerContent = new MultipartContent("mixed", boundary); innerContent.Add(new StringContent(innerText)); for (var cnt = 0; cnt < nesting; cnt++) { string outerBoundary = String.Format("{0}_{1}", boundary, cnt); MultipartContent outerContent = new MultipartContent("mixed", outerBoundary); outerContent.Add(innerContent); innerContent = outerContent; } MemoryStream memStream = new MemoryStream(); innerContent.CopyToAsync(memStream).Wait(); memStream.Position = 0; byte[] data = memStream.ToArray(); HttpContent content = new ByteArrayContent(data); content.Headers.ContentType = innerContent.Headers.ContentType; for (var cnt = 0; cnt < nesting + 1; cnt++) { Task <IEnumerable <HttpContent> > task = content.ReadAsMultipartAsync(); task.Wait(TimeoutConstant.DefaultTimeout); IEnumerable <HttpContent> result = task.Result; Assert.Equal(1, result.Count()); content = result.ElementAt(0); Assert.NotNull(content); } string text = content.ReadAsStringAsync().Result; Assert.Equal(innerText, text); }
public void SelectResponseMediaTypeMatchesResponseContentType(MediaTypeHeaderValue mediaType) { MockMediaTypeFormatter formatter = new MockMediaTypeFormatter() { CallBase = true }; formatter.SupportedMediaTypes.Add(mediaType); HttpRequestMessage request = new HttpRequestMessage(); HttpResponseMessage response = new HttpResponseMessage() { RequestMessage = request, Content = new StringContent("fred") }; response.Content.Headers.ContentType = mediaType; ResponseMediaTypeMatch match = formatter.SelectResponseMediaType(typeof(string), request); Assert.NotNull(match); Assert.Equal(ResponseFormatterSelectionResult.MatchOnResponseContentType, match.ResponseFormatterSelectionResult); Assert.NotNull(match.MediaTypeMatch.MediaType); Assert.Equal(mediaType.MediaType, match.MediaTypeMatch.MediaType.MediaType); }
public void SetResolverFunc() { // Arrange HttpConfiguration config = new HttpConfiguration(); DependencyResolver resolver = new DependencyResolver(config); Mock <CommonServiceLocatorSlim> userResolverMock = new Mock <CommonServiceLocatorSlim>(); IHttpActionSelector actionSelector = new Mock <IHttpActionSelector>().Object; resolver.SetResolver(_ => actionSelector, _ => new List <object> { actionSelector }); // Act object service = resolver.GetService(typeof(IHttpActionSelector)); IEnumerable <object> services = resolver.GetServices(typeof(IHttpActionSelector)); // Assert userResolverMock.Verify(); Assert.Same(actionSelector, service); Assert.Same(actionSelector, services.ElementAt(0)); }