Hi I'm trying to run a simple test replacing Features.Count on every SPSite, but I can't. Can you help me?
I have this code:
[TestMethod]
public void AllInstances()
{
using (var context = new SPEmulationContext(IsolationLevel.Fake))
{
ShimSPSite.AllInstances.FeaturesGet = (item) =>
{
return new ShimSPFeatureCollection()
{
CountGet = () => 1
}.Instance;
};
var tSite = new SPSite("http://fakesite");
Assert.AreEqual(1, tSite.Features.Count);
}
}
but it fails with this exception:
Microsoft.QualityTools.Testing.Fakes.Shims.ShimNotImplementedException: Exception of type 'Microsoft.QualityTools.Testing.Fakes.Shims.ShimNotImplementedException' was thrown.
This one which is similar works fine
[TestMethod]
public void Shim()
{
using (var context = new SPEmulationContext(IsolationLevel.Fake))
{
var tSite = new ShimSPSite()
{
FeaturesGet = () =>
{
return new ShimSPFeatureCollection()
{
CountGet = () => 1
}.Instance;
}
}.Instance;
Assert.AreEqual(1, tSite.Features.Count);
}
}
Can you tell me what I'm doing wrong?
Thanks
Related
I am onboarding alone on an existing project that do not have any unit test. My first goal before any refactoring is to cover 100% of the code. I would like to avoid any regression.
I have read how do I mock sqlconnection or should I refactor the code? but my case as you can see below is quite different cause I need to do more than stub simply the sqlConnection. Basically, I need to mock the db. I would like to know the best approach to achieve it.
(By the way, I do not want to use any ORM such as Entity).
Below the code of the repository :
public class HotelRepository : IHotelRepository
{
private readonly IDbConnection _dbConnection;
private readonly ILogService _loggerService;
public HotelRepository(IDbConnection dbConnection, ILogService loggerService)
{
_dbConnection = dbConnection;
_loggerService = loggerService;
}
public HotelDo GetByRid(string rid)
{
return Find(rid).FirstOrDefault();
}
public List<HotelDo> Find(string text)
{
try
{
_dbConnection.Open();
var items = new List<HotelDo>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelSearchByRidOrName";
command.Parameters.Add(new SqlParameter("#Text", text));
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
items.Add(new HotelDo()
{
Name = SqlExtension.ReaderToStringConverter(reader["Name"]),
Id = SqlExtension.ReaderToIntConverter(reader["Id"]),
Rid = SqlExtension.ReaderToStringConverter(reader["RIDHotel"]),
IdPms = SqlExtension.ReaderToNullableIntConverter(reader["IdPms"]),
LinkResaWeb = SqlExtension.ReaderToStringConverter(reader["LinkResaWeb"]),
LinkPms = SqlExtension.ReaderToStringConverter(reader["LinkPms"]),
IdBrand = SqlExtension.ReaderToNullableIntConverter(reader["IdBrand"]) ?? 0,
IsOnline = SqlExtension.ReaderToBoolConverter(reader["IsOnline"]) ?? false,
CodeCountry = SqlExtension.ReaderToStringConverter(reader["CodeCountry"])
});
}
}
}
return items;
}
catch (Exception e)
{
var errorMessage = $"HotelRepository Find, text {text} ";
_loggerService.Trace(LogSeverity.Error, errorMessage, e);
throw new DalException() { Source = errorMessage, };
}
finally
{
_dbConnection.Close();
}
}
public List<HotelDo> GetAll()
{
try
{
_dbConnection.Open();
var items = new List<HotelDo>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelGetAll";
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
bool.TryParse(reader["IsOnline"].ToString(), out var isOnline);
items.Add(new HotelDo()
{
Id = SqlExtension.ReaderToIntConverter(reader["Id"]),
Rid = SqlExtension.ReaderToStringConverter(reader["RIDHotel"]),
Name = SqlExtension.ReaderToStringConverter(reader["Name"]),
CodeCountry = SqlExtension.ReaderToStringConverter(reader["CodeCountry"]),
LinkPms = SqlExtension.ReaderToStringConverter(reader["LinkPms"]),
IdPms = SqlExtension.ReaderToNullableIntConverter(reader["IdPms"]),
IdBrand = SqlExtension.ReaderToNullableIntConverter(reader["IdBrand"]) ?? 0,
LinkResaWeb = SqlExtension.ReaderToStringConverter(reader["LinkResaWeb"]),
IsOnline = isOnline
});
}
}
}
return items;
}
catch (Exception e)
{
var errorMessage = $"HotelRepository GetAllHotels";
_loggerService.Trace(LogSeverity.Error, errorMessage, e);
throw new DalException() { Source = errorMessage, };
}
finally
{
_dbConnection.Close();
}
}
}
Thank you for your help
So based on what you've got I've set up a test frame for you to follow. I've removed less important components for breviety.
Before you you jump in I just want to give my 2 cents, if you don't know how to do this sort of thing you seem to be more or less in a junior position or less experiance with C# and also found your self in a more or less mature company that doesn't care about the development deparment, since an uncovered project just get's thrown your way says you don't have alot of resources to go about to imrpove the code base.
Test only the things that have business value (can you put a price on the piece of logic if it brakes)
Delivering stuff faster will make you look better as a programmer (noone in the business gives a damn about test covarage)
Study hard, get your experiance, good reputation and don't be afraid to get the hell out of there as soon as you start getting bored.
Main
void Main()
{
var idIndex = 0;
var ids = new string[] { "1", "2" };
var mockDataReader = new Mock<IDataReader>();
mockDataReader.SetupSequence(x => x.Read()).Returns(true).Returns(true).Returns(false);
mockDataReader.SetupGet(x => x["Id"]).Returns(() => ids[idIndex]).Callback(() => idIndex++);
var mockParameters = new Mock<IDataParameterCollection>();
var mockCommand = new Mock<IDbCommand>();
mockCommand.SetupGet(x => x.Parameters).Returns(mockParameters.Object);
mockCommand.Setup(x => x.ExecuteReader(CommandBehavior.CloseConnection)).Returns(mockDataReader.Object);
var mockConnection = new Mock<IDbConnection>();
mockConnection.Setup(x => x.CreateCommand()).Returns(mockCommand.Object);
var repo = new HotelRepository(mockConnection.Object);
var result = repo.Find("search");
Assert.Equal("1", result[0].Id);
Assert.Equal("2", result[1].Id);
}
Repository
public class HotelRepository
{
private readonly IDbConnection _dbConnection;
public HotelRepository(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public List<Pony> Find(string text)
{
_dbConnection.Open();
var items = new List<Pony>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelSearchByRidOrName";
command.Parameters.Add(new SqlParameter("#Text", text));
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
items.Add(new Pony
{
Id = reader["Id"].ToString()
});
}
}
}
return items;
}
}
Just a dumb o'l pony
public class Pony {
public string Id { get; set; }
}
I am getting a NotSupportedException error message on my Unit Test using Moq.
I have the following test which mocks the result.
public class Person
{
public string Id { get; set; }
}
[Test]
public void List_Should_List_All_People()
{
//Arrange
const long total = 3;
var list = new List<Person>();
var queryResponse = new Mock<Task<ISearchResponse<Person>>>();
queryResponse.Setup(x => x.Result.Total).Returns(total);
for (var i = 0; i < total; i++)
{
list.Add(new Person { Id = Guid.NewGuid().ToString() });
}
queryResponse.Setup(x => x.Result.Documents).Returns(list);
Thread.Sleep(2000);
_elasticClient.Setup(x => x.SearchAsync(It.IsAny<Func<SearchDescriptor<Person>, ISearchRequest>>())).Returns(queryResponse.Object);
// Act
var response = _repository.List<Person>();
//Assert
response.Count().Should().Be(3);
}
queryResponse.Setup(x => x.Result.Total).Returns(total); <-- an exception is thrown
Invalid setup on a non-virtual (overridable in VB) member: mock => mock.Result
It works synchronously without any problems.
Any suggestions how to get around this exception?
How can I set it as virtual?
You mock the Task<ISearchResponse<Person>> but not the ISearchResponse<Person> task result.
Here's an example of mocking a task result; you don't have all of the types that you're working with in your example so I've simplified this a little
async void Main()
{
var elasticClient = new Mock<IElasticClient>();
//Arrange
const long total = 3;
var list = new List<Person>();
for (var i = 0; i < total; i++)
{
list.Add(new Person { Id = Guid.NewGuid().ToString() });
}
var searchResponse = new Mock<ISearchResponse<Person>>();
searchResponse.Setup(x => x.Total).Returns(total);
searchResponse.Setup(x => x.Documents).Returns(list);
_elasticClient.Setup(x => x.SearchAsync(It.IsAny<Func<SearchDescriptor<Person>, ISearchRequest>>()))
.ReturnsAsync(searchResponse.Object);
// Act
var response = await elasticClient.Object.SearchAsync<Person>(s => s.MatchAll());
//Assert
// outputs 3
Console.WriteLine(response.Documents.Count());
}
public class Person
{
public string Id { get; set; }
}
The source IQueryable doesn't implement IDbAsyncEnumerable.
Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations.
For more details see http://go.microsoft.com/fwlink/?LinkId=287068.
I am new to NUnit.
I have developed the Nunit test cases for` async queries.
But I am getting above error. I refereed https://msdn.microsoft.com/en-us/data/dn314429.aspx link but not able
to solve error.
Any kind of help will be appreciated!
Thanks in advance!
public interface IWork : IDisposable
{
IBlogRepository BlogRepository { get; }
IDBContext Db { get; }
}
public class BlogRepository : GenericRepository<Blog>, IBlogRepository
{
internal ContainerRepository(IWork work)
: base(work)
{
}
}
public interface IBlogRepository : IGenericRepository<Blog>
{
}
[TestFixture]
public class AsyncQueryTests
{
[Test]
public async Task GetAllBlogsAsync_orders_by_name()
{
using (var work = ObjectFactory.GetInstance<IWork>())
{
var data = new List<Blog>
{
new Blog { Name = "BBB" },
new Blog { Name = "ZZZ" },
new Blog { Name = "AAA" },
}.AsQueryable();
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IDbAsyncEnumerable<Blog>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<Blog>(data.GetEnumerator()));
mockSet.As<IQueryable<Blog>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<Blog>(data.Provider));
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<IWork>();
mockContext.Setup(c => c.BlogRepository.GetQuery()).Returns(mockSet.Object);
ObjectFactory.Configure(cfg => cfg.For<IWork>().Use(mockContext.Object));
foreach (var blog in mockSet.Object)
{
mockContext.Object.BlogRepository.Add(blog);
}
var service = new BlogController();
var blogs = await service.GetAllBlogsAsync();
Assert.AreEqual(3, blogs.Count);
}
}
}
I would like to mock a WebViewPage and compare the output with an expected result.
here are my mockhelpers I'm using
public static class MockHelpers
{
public static HttpContextBase MockHttpContext(NameValueCollection queryStringCollection = null)
{
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
if(queryStringCollection != null)
SetupMockRequestQuerystringValues(request, queryStringCollection);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method
context.SetupGet(p => p.User.Identity.Name).Returns("blah");
context.SetupGet(p => p.User.Identity.IsAuthenticated).Returns(true);
return context.Object;
}
private static void SetupMockRequestQuerystringValues( Mock<HttpRequestBase> request, NameValueCollection queryStringCollection)
{
request.SetupGet(x => x.QueryString).Returns(queryStringCollection);
}
public static ViewContext MockViewContext()
{
return CreateSimpleGenericMock<ViewContext>();
}
public static T MockWebViewPage<T>() where T : WebViewPage
{
var mock = new Mock<T>(MockBehavior.Loose) { CallBase = true };
mock.SetupGet(x => x.Context).Returns(MockHttpContext());
mock.SetupGet(x => x.Layout).Returns("layoutName");
mock.SetupGet(x => x.VirtualPath).Returns("virtualPathName");
mock.SetupGet(x => x.Page).Returns(new object{});
mock.SetupGet(x => x.PageData).Returns(new Dictionary<object, dynamic>()
{
{new object(), new object()}
});
var page = mock.Object;
//var helper = new HtmlHelper<object>(new ViewContext { ViewData = CreateSimpleGenericMock<ViewDataDictionary>() }, page, CreateSimpleGenericMock<RouteCollection>());
var helper = new HtmlHelper<object>(new ViewContext { ViewData = new ViewDataDictionary() }, page, new RouteCollection());
page.ViewContext = MockViewContext();
page.Html = helper;
return page;
}
public static T CreateSimpleGenericMock<T>() where T : class
{
var mock = new Mock<T>();
return mock.Object;
}
}
In the MockWebViewPage method you can see all that I have faked. My test method looks like so
[TestMethod]
public void TestMethod1()
{
var coreMasterTestClass = MockHelpers.MockWebViewPage<CoreMaster<object>>();
coreMasterTestClass.ExecutePageHierarchy();
var output = coreMasterTestClass.Html;
}
Is it possible to test the output that will be generated with mocking, and if not does anyone have any possible clues how I could test this. Please note that I'm not testing actual chstml pages but core pages within our own framework.
I'm new to nUnit and I've been tasked with creating unit tests for some htmlhelper extension methods.
How should I go about creating a unit test for the following method?
public static MvcHtmlString EnumDropDownListForOrderBy<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, bool orderById, string firstElement = null, object htmlAttributes = null)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = values.Select(value => new SelectListItem()
{
Text = value.GetAttributeFrom<DescriptionAttribute>(value.ToString()).Description,
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
});
IEnumerable<SelectListItem> itemsFiltered = items.Where(e => !string.IsNullOrEmpty(e.Text)).AsEnumerable();
itemsFiltered = itemsFiltered.OrderBy(e => (orderById ? e.Text : e.Value));
return htmlHelper.DropDownListFor(
expression,
itemsFiltered,
firstElement,
htmlAttributes
);
}
Any help would be appreciated
Below is how you write a Unit Test for this. Note that since you have not specified that you use a Mock object framework I'm going to the poor man technique, which is the hand written stubs and mocks. There is also another helper method if you are using Moq.
It is important to note that, in order to simplify the code execution I have made couple of changes to your extension method, so the test would not fail unexpectedly. Checking for any unexpected behaver is a good defensive programming practice anyway.
Back to the tests.
SUT (System Under Test)
This is how the SUT (System Under Test) looks like and supporting types looks like. (Please feel free to modify to your need accordingly)
public static class MyHtmlHelper
{
public static MvcHtmlString EnumDropDownListForOrderBy<TModel, TEnum>
(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TEnum>> expression,
bool orderById, string firstElement = null, object htmlAttributes = null,
Func<ModelMetadata> fromLambFunc = null)
{
ModelMetadata metadata =
ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items =
values.Select(value => new SelectListItem()
{
Text = GetText(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
});
IEnumerable<SelectListItem> itemsFiltered =
items.Where(e => !string.IsNullOrEmpty(e.Text)).AsEnumerable();
itemsFiltered = itemsFiltered.OrderBy(e => (orderById ? e.Text : e.Value));
return htmlHelper.DropDownListFor
(expression, itemsFiltered, firstElement, htmlAttributes);
}
private static Type GetNonNullableModelType(ModelMetadata metadata) {
return typeof (SomeEnum);
}
private static string GetText<TEnum>(TEnum value) {
return value.GetAttributeFrom<DescriptionAttribute>(value.ToString()) != null
? value.GetAttributeFrom<DescriptionAttribute>(value.ToString()).Description
: string.Empty;
}
}
public static class ExtensionMethodsAttr
{
public static T GetAttributeFrom<T>(this object instance, string propertyName)
where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return property != null ?
(T)property.GetCustomAttributes(attrType, false).First() : default(T) ;
}
}
public enum SomeEnum { A,}
Unit Tests
[TestFixture]
public class HtmlHelperTests
{
[Test]
public void EnumDropDownListForOrderBy_InvokeDropDownListFor_ReturnsExpectedSelectItemResult()
{
//Arrange
var expected = "<select id=\"Foo\" name=\"Foo\"></select>";
var fakeHtmlHelper = CreateHtmlHelperStaticStubs
(new ViewDataDictionary(new FakeViewModel() {Foo = SomeEnum.A}));
//var fakeHtmlHelper = CreateHtmlHelperUsingMoq
(new ViewDataDictionary(new FakeViewModel(){Foo = SomeEnum.A}));
//Act
var result = fakeHtmlHelper.EnumDropDownListForOrderBy
(model => model.Foo, It.IsAny<bool>(), null, null, null);
//Assert
Assert.AreEqual(expected, result.ToString());
}
private static HtmlHelper<FakeViewModel>
CreateHtmlHelperStaticStubs(ViewDataDictionary viewData)
{
var stubControllerContext = new ControllerContext(new FakeHttpContext(), new RouteData(), new FakeController());
var stubViewContext = new ViewContext(stubControllerContext, new FakeView(),
new ViewDataDictionary(new FakeViewModel() { Foo = SomeEnum.A }),
new TempDataDictionary(), new TextMessageWriter());
var fakeViewDataContainer = new FakeViewDataContainer();
fakeViewDataContainer.ViewData = viewData;
return new HtmlHelper<FakeViewModel>(stubViewContext, fakeViewDataContainer);
}
//Moq version
private static HtmlHelper<FakeViewModel>
CreateHtmlHelperUsingMoq(ViewDataDictionary viewData)
{
var stubControllerContext = new Mock<ControllerContext>();
stubControllerContext.Setup(x => x.HttpContext).Returns(new Mock<HttpContextBase>().Object);
stubControllerContext.Setup(x => x.RouteData).Returns(new RouteData());
stubControllerContext.Setup(x => x.Controller).Returns(new Mock<ControllerBase>().Object); ;
var stubViewContext = new Mock<ViewContext>();
stubViewContext.Setup(x => x.View).Returns(new Mock<IView>().Object);
stubViewContext.Setup(x => x.ViewData).Returns(viewData);
stubViewContext.Setup(x => x.TempData).Returns(new TempDataDictionary());
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(viewData);
return new HtmlHelper<FakeViewModel>(stubViewContext.Object, mockViewDataContainer.Object);
}
}
class FakeHttpContext : HttpContextBase
{
private Dictionary<object, object> _items = new Dictionary<object, object>();
public override IDictionary Items { get { return _items; } }
}
class FakeViewDataContainer : IViewDataContainer
{
private ViewDataDictionary _viewData = new ViewDataDictionary();
public ViewDataDictionary ViewData { get { return _viewData; } set { _viewData = value; } }
}
class FakeController : Controller { }
class FakeView : IView
{
public void Render(ViewContext viewContext, System.IO.TextWriter writer)
{
throw new NotImplementedException();
}
}
public class FakeViewModel {
public SomeEnum Foo { get; set; }
}