The following setups were not matched - converting JustMock to Moq - tdd

I am going through this tutorial http://blogs.telerik.com/justteam/posts/13-10-25/30-days-of-tdd-day-17-specifying-order-of-execution-in-mocks in regards to TDD. I am attempting to adapt a JustMock statement to Moq.
enter code here [Test]
public void testname()
{
var customerId = Guid.NewGuid();
var customerToReturn = new Customer { Id = customerId};
//JustCode
Mock _customerService = Mock.Create<ICustomerService>();
Mock.Arrange(() => _customerService.GetCustomer(customerId)).Returns(customer).OccursOnce();
//Moq
Mock<ICustomerService> _customerService = new Mock <ICustomerService>();
_customerService.Setup(os => os.GetCustomer(customerId)).Returns(customerToReturn);
_customerService.VerifyAll();
}
When the test is ran, I get this exception:
Moq.MockVerificationException : The following setups were not matched:ICustomerService os => os.GetCustomer(a1a0d25c-e14a-4c68-ade9-bc3d7dd5c2bc)
When I change .VerifyAll() to .Verify(), the test passes, but I am uncertain if this is correct.
Question: What is the proper way to adapt this code? Is .VerifyAll() not similiar to .OccursOnce()?

It seems you are missing the .verifiable on the setup. Also you can avoid any verifiable , just use the mock.Verify at the end. You must also call the mocked instance so the verifable work.
https://github.com/Moq/moq4/wiki/Quickstart
Please see 2 approaches below.
[Test]
public void testname()
{
var customerId = Guid.NewGuid();
var customerToReturn = new Customer { Id = customerId};
//Moq
var _customerService = new Mock <ICustomerService>();
_customerService.Setup(os => os.GetCustomer(customerId)).Returns(customerToReturn).Verifiable();
var cust = _customerService.Object.GetCustomer(customerId);
_customerService.VerifyAll();
}
[Test]
public void testname1()
{
var customerId = Guid.NewGuid();
var customerToReturn = new Customer { Id = customerId };
//Moq
var _customerService = new Mock<ICustomerService>();
_customerService.Setup(os => os.GetCustomer(customerId)).Returns(customerToReturn);
var cust = _customerService.Object.GetCustomer(customerId);
_customerService.Verify(x => x.GetCustomer(customerId));
}

Related

Entity Framework Core 3.1 - Linq - Could not be translated. Either rewrite the query in a form that can be translated

When I try to use a select in a Linq query and create a viewmodel in the select statement, it works. When I try to extract the creation of the viewmodel to a static method, it gives the following error: "Could not be translated. Either rewrite the query in a form that can be translated". Why is this happening?
The calling of SiteViewModel.GetSiteViewModel(s) generates this error.
public async Task<IEnumerable<ContractViewModel>> ExecuteAsync(CancellationToken token = new CancellationToken())
{
var contracts = await _domainContext.Contracts.Include(s => s.Sites)
.AuthorizedFor(User)
.Select(c => new ContractViewModel()
{
CreationDate = c.CreationDate,
ContractId = c.Id,
ContractLineWiatingForConfirmation = c.ContractLines.Any(l => l.Status == ContractLineStatus.WaitingForConfirmation),
ModificationDate = c.ModificationDate,
ExpirationDate = c.ExpirationDate,
Title = c.Title,
Status = c.Status,
Sites = c.Sites.Select(s => SiteViewModel.GetSiteViewModel(s)).OrderBy(s => s.SiteName)
})
.ToListAsync(token);
return contracts;
}
GetSiteViewModel looks like this:
public static SiteViewModel GetSiteViewModel(ContractSite x)
{
return new SiteViewModel
{
SiteId = x.Site.Id,
SiteCode = x.Site.Code,
SiteName = x.Site.Name,
AgressoCode = x.Site?.ExternalReference?.Identifier,
AgressoAdministration = x.Site?.ExternalReference?.Source
};
}
Update:
When I remove the orderby, it works. When I remove the static method to create a viewmodel, and place the creation of the viewmodel in the query itself and DONT remove the orderby, it then also works...
It is because LINQ translator can not look into your GetSiteViewModel method body and recognize how properties are remapped.
Simplest fix, is to do OrderBy before GetSiteViewModel call
Sites = c.Sites.OrderBy(s => s.Site.Name).Select(s => SiteViewModel.GetSiteViewModel(s))
But if it is not an option, then you can solve that by several methods.
Simplest and without third-party dependencies is to change your function to return IQueryable
public static class MyDtoExtensions
{
public static IQueryable<SiteViewModel> GetSiteViewModel(this IQueryable<ContractSite> query)
{
return query.Select(x => new SiteViewModel
{
SiteId = x.Site.Id,
SiteCode = x.Site.Code,
SiteName = x.Site.Name,
AgressoCode = x.Site?.ExternalReference?.Identifier,
AgressoAdministration = x.Site?.ExternalReference?.Source
};
}
}
Then you can use this extension:
Sites = c.Sites.AsQueryable().GetSiteViewModel().OrderBy(s => s.SiteName)
But for better extensibility I would suggest to use this extension (similar functionality is coming with LINQKit)
https://github.com/axelheer/nein-linq/
And rewrite your function
public static class MyDtoExtensions
{
[InjectLambda]
public static SiteViewModel GetSiteViewModel(this ContractSite x)
{
_getSiteViewModel =?? GetSiteViewModel().Compile();
return _getSiteViewModel(x);
}
private static Func<ContractSite, SiteViewModel> _getSiteViewModel;
private static Expression<Func<ContractSite, SiteViewModel>> GetSiteViewModel()
{
return x => new SiteViewModel
{
SiteId = x.Site.Id,
SiteCode = x.Site.Code,
SiteName = x.Site.Name,
AgressoCode = x.Site?.ExternalReference?.Identifier,
AgressoAdministration = x.Site?.ExternalReference?.Source
};
}
}
Then you can use GetSiteViewModel in queries without limitations. But do not forget to call ToEntityInjectable()
public async Task<IEnumerable<ContractViewModel>> ExecuteAsync(CancellationToken token = default)
{
var contracts = await _domainContext.Contracts
.ToEntityInjectable()
.Include(s => s.Sites)
.AuthorizedFor(User)
.Select(c => new ContractViewModel()
{
CreationDate = c.CreationDate,
ContractId = c.Id,
ContractLineWiatingForConfirmation = c.ContractLines.Any(l => l.Status == ContractLineStatus.WaitingForConfirmation),
ModificationDate = c.ModificationDate,
ExpirationDate = c.ExpirationDate,
Title = c.Title,
Status = c.Status,
Sites = c.Sites.Select(s => s.GetSiteViewModel()).OrderBy(s => s.SiteName)
})
.ToListAsync(token);
return contracts;
}

IQueryable.Union/Concat in .net core 3

I want to add a dummy member to an IQueryable and came up with this solution:
IQueryable<Geography> geographies = _unitOfWork.GeographyRepository.GetAll(); //DbSet<Geography>
var dummyGeographies = new Geography[] { new Geography { Id = -1, Name = "All" } }.AsQueryable();
var combinedGeographies = geographies.Union(dummyGeographies);
var test = combinedGeographies.ToList(); //throws runtime exc
But it throws the following exception:
Processing of the LINQ expression 'DbSet
.Union(EnumerableQuery { Geography, })' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core.
How could I make it work?!
you can only union on data structure which are the same
IQueryable is only applicable if the query expression not been been expressed (ToList) before its run against db and you want the expression modifiable . aka nothing which which is not going to db as a query needs to be IQueryable (simple explanation better to research and understand this yourself)
List<Geography> geographies = _unitOfWork.GeographyRepository
.GetAll() //DbSet<Geography>
.Select(o => new Geography { Id = o.Id, Name = o.Name })
.ToList();
List<Geography> dummyGeographies = new List<Geography>() {
new Geography[] { new Geography { Id = -1, Name = "All" } }
};
var combinedGeographies = geographies.Union(dummyGeographies);
var test = combinedGeographies.ToList();
I was able to achieve it with the following code:
IQueryable<Geography> geographies = _unitOfWork.GeographyRepository.GetAll().Select(o => new Geography { Id = o.Id, Name = o.Name });
IQueryable<Geography> dummyGeographies = _unitOfWork.GeographyRepository.GetAll().Select(o => new Geography { Id = -1, Name = "All" });
var combinedGeographies = geographies.Union(dummyGeographies);

ElasticSearch NEST 5.6.1 Query for unit test

I wrote a bunch of queries to elastic search and I wanted to write a unit test for them. using this post moq an elastic connection I was able to preform a general mocking. But When I tried to view the Json which is being generated from my query I didn't manage to get it in any way.
I tried to follow this post elsatic query moq, but it is relevant only to older versions of Nest because the method ConnectionStatus and RequestInformation is no longer available for an ISearchResponse object.
My test look as follow:
[TestMethod]
public void VerifyElasticFuncJson()
{
//Arrange
var elasticService = new Mock<IElasticService>();
var elasticClient = new Mock<IElasticClient>();
var clinet = new ElasticClient();
var searchResponse = new Mock<ISearchResponse<ElasticLog>>();
elasticService.Setup(es => es.GetConnection())
.Returns(elasticClient.Object);
elasticClient.Setup(ec => ec.Search(It.IsAny<Func<SearchDescriptor<ElasticLog>,
ISearchRequest>>())).
Returns(searchResponse.Object);
//Act
var service = new ElasticCusipInfoQuery(elasticService.Object);
var FindFunc = service.MatchCusip("CusipA", HostName.GSMSIMPAPPR01,
LogType.Serilog);
var con = GetConnection();
var search = con.Search<ElasticLog>(sd => sd
.Type(LogType.Serilog)
.Index("logstash-*")
.Query(q => q
.Bool(b => b
.Must(FindFunc)
)
)
);
**HERE I want to get the JSON** and assert it look as expected**
}
Is there any other way to achieve what I ask?
The best way to do this would be to use the InMemoryConnection to capture the request bytes and compare this to the expected JSON. This is what the unit tests for NEST do. Something like
private static void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection())
.DefaultIndex("default")
.DisableDirectStreaming();
var client = new ElasticClient(connectionSettings);
// Act
var searchResponse = client.Search<Question>(s => s
.Query(q => (q
.Match(m => m
.Field(f => f.Title)
.Query("Kibana")
) || q
.Match(m => m
.Field(f => f.Title)
.Query("Elasticsearch")
.Boost(2)
)) && +q
.Range(t => t
.Field(f => f.Score)
.GreaterThan(0)
)
)
);
var actual = searchResponse.RequestJson();
var expected = new
{
query = new {
#bool = new {
must = new object[] {
new {
#bool = new {
should = new object[] {
new {
match = new {
title = new {
query = "Kibana"
}
}
},
new {
match = new {
title = new {
query = "Elasticsearch",
boost = 2d
}
}
}
},
}
},
new {
#bool = new {
filter = new [] {
new {
range = new {
score = new {
gt = 0d
}
}
}
}
}
}
}
}
}
};
// Assert
Console.WriteLine(JObject.DeepEquals(JToken.FromObject(expected), JToken.Parse(actual)));
}
public static class Extensions
{
public static string RequestJson(this IResponse response) =>
Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);
}
I've used an anonymous type for the expected JSON as it's easier to work with than an escaped JSON string.
One thing to note is that Json.NET's JObject.DeepEquals(...) will return true even when there are repeated object keys in a JSON object (so long as the last key/value matches). It's not likely something you'll encounter if you're only serializing NEST searches though, but something to be aware of.
If you're going to have many tests checking serialization, you'll want to create a single instance of ConnectionSettings and share with all, so that you can take advantage of the internal caches within it and your tests will run quicker than instantiating a new instance in each test.

Can XUnit interfere with the code?

I recently have a very weird behaviour, so weird I'm starting to wonder if the culprit could be the unit framework I'm using (XUnit). I asked a question about it there: Can Expressmapper copy to destination? but this one is no longer about Expressmapper but about XUnit.
Do you know if in some way XUnit can intefere with the code?
Here's a the reason I'm asking:
I can run those 'together or separatly) in any order and I always get this crazy behaviour:
First test fails (Test_xxx)
Second test pass (Test_Map)
Both tests contain the very same code!!
[Fact]
[Trait("Test kind", "Integration")]
public void Test_xxx()
{
// Arrange
var mapper = new MappingServiceProvider();
mapper.Register<MapSource, MapDestination>();
var src = new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid(),
Parent = new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid()
}
};
src.Children = Enumerable.Range(0, 3).Select(i => new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid()
}).ToList();
var dst = new MapDestination();
// Act
mapper.Map(src, dst);
// Assert
var compare = new CompareLogic(new ComparisonConfig
{
IgnoreObjectTypes = true
});
var comparison = compare.Compare(src, dst);
Assert.Equal(new List<Difference>(), comparison.Differences);
}
[Fact]
[Trait("Test kind", "Integration")]
public void Test_Map()
{
// Arrange
var mapper = new MappingServiceProvider();
mapper.Register<MapSource, MapDestination>();
var src = new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid(),
Parent = new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid()
}
};
src.Children = Enumerable.Range(0, 3).Select(i => new MapSource
{
Id = Guid.NewGuid().GetHashCode(),
Guid = Guid.NewGuid()
}).ToList();
var dst = new MapDestination();
// Act
mapper.Map(src, dst);
// Assert
var compare = new CompareLogic(new ComparisonConfig
{
IgnoreObjectTypes = true
});
var comparison = compare.Compare(src, dst);
Assert.Equal(new List<Difference>(), comparison.Differences);
}
I had another method called Test_Map (with a different signature; aka overload).
I guess XUnit requires method name to be unique (something I intended to do).

Can't get IEnumerable type using linq filtered query

i have been finding problems related to the following code..Actually i want to select filtered records but it gives me 0 records. I have tried the following. Please Help me..
public static IEnumerable<PostModel> GetPostData(string cat)
{
var data = new LinqClassDataContext(); IEnumerable<PostModel> pm;
pm=data.PostTables.Where(Post => new PostModel
{ CategoryName= Post.CategoryName}.Equals(cat)).Select
(Post => new PostModel
{ PostID = (int)Post.PostID,
PostSubject = Post.PostSubject,
PostAuthor = Post.PostAuthor,
PostDate = Post.PostDate,
PostContent = Post.PostContent,
CategoryName = Post.CategoryName
});
}
Why your PostModel class object would be Equals string cat?
Maybe you meant:
data.PostTables.Where(Post => Post.CategoryName == cat)
Even though you overrided Equals method on PostModel I think you should use line I meantioned above because it is more obvious.
Also at the end of query you should call .ToList() method for initiating it. And you should dispose context after creating it in the method.
public static IEnumerable<PostModel> GetPostData(string cat)
{
var data = new LinqClassDataContext();
var pm = data.PostTables.Where(post => post.CategoryName == cat)
.Select(Post => new PostModel
{
PostID = (int)Post.PostID,
PostSubject = Post.PostSubject,
PostAuthor = Post.PostAuthor,
PostDate = Post.PostDate,
PostContent = Post.PostContent,
CategoryName = Post.CategoryName
})
.ToList();
data.Dispose();
return pm;
}

Resources