xUnit, Moq - test .Net Core Repository - c#

I'm learning to write unit tests in xUnit and Moq, I have a problem somewhat. I wrote 2 tests in one, I add a category and download all, checking through Assert or whatever they are. In the second case, I also add categories, and I get the details of the added category, unfortunately I can not display the details of the downloaded category, it's the TestCategoryDetails test. What am I doing wrong?
using Moq;
using relationship.Models;
using Xunit;
using Xunit.Abstractions;
namespace Testy
{
public class UnitTest1
{
private readonly ITestOutputHelper _output;
public UnitTest1(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void TestCategoryList()
{
var categoryMock = new Mock<ICategoryRepository>();
var contextMock = new Mock<AppDbContext>();
categoryMock.Setup(x => x.AddCategory(new GameCategory { Id= 1, Name = "Tester" }));
var result = categoryMock.Object;
Assert.NotNull(result.GameCategory());
}
[Fact]
public void TestCategoryDetails()
{
var categoryMock = new Mock<ICategoryRepository>();
var contextMock = new Mock<AppDbContext>();
categoryMock.Setup(x => x.AddCategory(new GameCategory { Id = 1, Name = "Tester" }));
var result = categoryMock.Object;
var categoryDetails = result.GetDetails(1);
Assert.NotNull(categoryDetails);
}
}
}
In general, I wanted to test my repository by checking how add, edit, delete, download all categories and details of the selected one, unfortunately I'm not doing anything.

What are you doing is you are trying to test the mockup of the repository abstraction. But you want to test your implementation.
What works well to test with db context is to use in memory provider for the real context. For the details see:
https://learn.microsoft.com/en-us/ef/core/miscellaneous/testing/
At the end it may look like this (second test):
...
[Fact]
public void TestCategoryDetails()
{
// arrange
var categoryRepository = new CategoryRepository(GetContextWithInMemoryProvider());
// act
categoryRepository.AddCategory(new GameCategory { Id = 1, Name = "Tester" });
var categoryDetails = categoryRepository.GetDetails(1);
// assert
Assert.NotNull(categoryDetails);
}
private AppDbContext GetContextWithInMemoryProvider()
{
// create and configure context
// see: https://learn.microsoft.com/en-us/ef/core/miscellaneous/testing/
}
...

Related

How to write service test for UpdateAsync in Microsoft Graph API (Add multiple members to a group in a single request)

I am using Microsoft Graph Api client and performing add members to group.
Docs here :- https://learn.microsoft.com/en-us/graph/api/group-post-members?view=graph-rest-1.0&tabs=csharp#example-2-add-multiple-members-to-a-group-in-a-single-request
I have successfully achieved the requirement. But when come to write test for my service class having no clue what and how to verify it.
I am beginner to the API dev and also with Microsoft Graph API. Below are my codes, Take a look and post your suggestions and comments. It might be helpful.
Service Class:
public class UserGroupService : IUserGroupService
{
private readonly IGraphServiceClient _graphServiceClient;
public UserGroupService(IGraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task AddAsync(string groupId, IList<string> userIds)
{
var group = new Group
{
AdditionalData = new Dictionary<string, object>()
{
{"members#odata.bind", userIds.Select(x => $"https://graph.microsoft.com/v1.0/directoryObjects/{x}") }
}
};
await _graphServiceClient.Groups[groupId].Request().UpdateAsync(group);
}
}
ServiceTest :
public class UserGroupServiceTests
{
private readonly Fixture _fixture = new Fixture();
private readonly Mock<IGraphServiceClient> _graphServiceClientMock = new Mock<IGraphServiceClient>();
private readonly IUserGroupService _userGroupService;
public UserGroupServiceTests()
{
_userGroupService = new UserGroupService(_graphServiceClientMock.Object);
}
// Settingup GraphClientMock
private void SetupGraphClientMock(string groupId, IList<string> userIds, Group group)
{
var groupRequest = new Mock<IGroupRequest>();
var groupRequestBuilder = new Mock<IGroupRequestBuilder>();
groupRequest.Setup(x => x.UpdateAsync(group));
groupRequestBuilder.Setup(x => x.Request()).Returns(groupRequest.Object);
_graphServiceClientMock.Setup(x => x.Groups[groupId]).Returns(groupRequestBuilder.Object);
}
[Fact]
public async Task AddAsync_GivenValidInput_WhenServiceSuccessful_AddAsyncCalledOnce()
{
object result;
var groupId = _fixture.Create<string>();
var userIds = _fixture.Create<IList<string>>();
var dictionary = _fixture.Create<Dictionary<string, object>>();
dictionary.Add("members#odata.bind", userIds.Select(x => $"https://graph.microsoft.com/v1.0/directoryObjects/{x}"));
var group = _fixture.Build<Group>().With(s => s.AdditionalData, dictionary).OmitAutoProperties().Create();
SetupGraphClientMock(groupId, userIds, group);
await _userGroupService.AddAsync(groupId, userIds);
//TODO
// Need to verify _graphServiceClientMock AdditionalData value == mocking group AdditionalData value which is called once in _graphServiceClientMock.
// Below implementation done using TryGetValue which return bool, I am really afraid to write test using bool value and compare and I feel its not a right way to write test.
_graphServiceClientMock.Verify(m => m.Groups[groupId].Request().UpdateAsync(It.Is<Group>(x => x.AdditionalData.TryGetValue("members#odata.bind", out result) == group.AdditionalData.TryGetValue("members#odata.bind", out result))), Times.Once);
_graphServiceClientMock.VerifyNoOtherCalls();
}
}
I wants to verify _graphServiceClientMock AdditionalData value == mocking group AdditionalData value which is called once in _graphServiceClientMock like the above. Anyone have idea on this. Please post your comments.Thanks in Advance.
Based on the subject under test and the simplicity of the provided member under test the following example demonstrates how it can be tested in isolation,
public class UserGroupServiceTests {
[Fact]
public async Task AddAsync_GivenValidInput_WhenServiceSuccessful_AddAsyncCalledOnce() {
//Arrange
string groupId = "123456";
IList<string> userIds = new[] { "a", "b", "c" }.ToList();
string expectedKey = "members#odata.bind";
IEnumerable<string> expectedValues = userIds
.Select(x => $"https://graph.microsoft.com/v1.0/directoryObjects/{x}");
Group group = null;
Mock<IGraphServiceClient> clientMock = new Mock<IGraphServiceClient>();
clientMock
.Setup(x => x.Groups[groupId].Request().UpdateAsync(It.IsAny<Group>()))
.Callback((Group g) => group = g) //Capture passed group for assertion later
.ReturnsAsync(group) //To allow async flow
.Verifiable();
IUserGroupService _userGroupService = new UserGroupService(clientMock.Object);
//Act
await _userGroupService.AddAsync(groupId, userIds);
//Assert
clientMock.Verify(); //have verifiable expressions been met
clientMock.VerifyNoOtherCalls();
//Using FluentAssertions to assert captured group
group.Should().NotBeNull();//was a group passed
group.AdditionalData.Should().NotBeNull()// did it have data
.And.ContainKey(expectedKey);//and did the data have expected key
(group.AdditionalData[expectedKey] as IEnumerable<string>)
.Should().BeEquivalentTo(expectedValues);//are values as expected
}
}
Review the code comments to get an understanding of how the test was exercised to verify the expected behavior.
The intuitive nature of the used FluentAssertions should also help in understanding what is being asserted

MVC Mocking (Moq) - HttpContext.Current.Server.MapPath

I have a method I am attempting to Unit Test which makes use of HttpContext.Current.Server.MapPath as well as File.ReadAllLines as follows:
public List<ProductItem> GetAllProductsFromCSV()
{
var productFilePath = HttpContext.Current.Server.MapPath(#"~/CSV/products.csv");
String[] csvData = File.ReadAllLines(productFilePath);
List<ProductItem> result = new List<ProductItem>();
foreach (string csvrow in csvData)
{
var fields = csvrow.Split(',');
ProductItem prod = new ProductItem()
{
ID = Convert.ToInt32(fields[0]),
Description = fields[1],
Item = fields[2][0],
Price = Convert.ToDecimal(fields[3]),
ImagePath = fields[4],
Barcode = fields[5]
};
result.Add(prod);
}
return result;
}
I have a Unit Test setup which (as expected) fails:
[TestMethod()]
public void ProductCSVfileReturnsResult()
{
ProductsCSV productCSV = new ProductsCSV();
List<ProductItem> result = productCSV.GetAllProductsFromCSV();
Assert.IsNotNull(result);
}
I have since done a lot of reading on Moq and Dependancy Injection which I just dont seem to be able to implement. I have also seen a few handy answers on SO such as: How to avoid HttpContext.Server.MapPath for Unit Testing Purposes however I am just unable to follow it for my actual example.
I am hoping someone is able to take a look at this and tell me exactly how I might go about implementing a successful test for this method. I feel I have a lot of the background required but am unable to pull it all together.
In its current form, the method in question is too tightly coupled to implementation concerns that are difficult to replicate when testing in isolation.
For your example, I would advise abstracting all those implementation concerns out into its own service.
public interface IProductsCsvReader {
public string[] ReadAllLines(string virtualPath);
}
And explicitly inject that as a dependency into the class in question
public class ProductsCSV {
private readonly IProductsCsvReader reader;
public ProductsCSV(IProductsCsvReader reader) {
this.reader = reader;
}
public List<ProductItem> GetAllProductsFromCSV() {
var productFilePath = #"~/CSV/products.csv";
var csvData = reader.ReadAllLines(productFilePath);
var result = parseProducts(csvData);
return result;
}
//This method could also eventually be extracted out into its own service
private List<ProductItem> parseProducts(String[] csvData) {
List<ProductItem> result = new List<ProductItem>();
//The following parsing can be improved via a proper
//3rd party csv library but that is out of scope
//for this question.
foreach (string csvrow in csvData) {
var fields = csvrow.Split(',');
ProductItem prod = new ProductItem() {
ID = Convert.ToInt32(fields[0]),
Description = fields[1],
Item = fields[2][0],
Price = Convert.ToDecimal(fields[3]),
ImagePath = fields[4],
Barcode = fields[5]
};
result.Add(prod);
}
return result;
}
}
Note how the class now is not concerned with where or how it gets the data. Only that it gets the data when asked.
This could be simplified even further but that is outside of the scope of this question. (Read up on SOLID principles)
Now you have the flexibility to mock the dependency for testing at a high level, expected behavior.
[TestMethod()]
public void ProductCSVfileReturnsResult() {
var csvData = new string[] {
"1,description1,Item,2.50,SomePath,BARCODE",
"2,description2,Item,2.50,SomePath,BARCODE",
"3,description3,Item,2.50,SomePath,BARCODE",
};
var mock = new Mock<IProductsCsvReader>();
mock.Setup(_ => _.ReadAllLines(It.IsAny<string>())).Returns(csvData);
ProductsCSV productCSV = new ProductsCSV(mock.Object);
List<ProductItem> result = productCSV.GetAllProductsFromCSV();
Assert.IsNotNull(result);
Assert.AreEqual(csvData.Length, result.Count);
}
For completeness here is what a production version of the dependency could look like.
public class DefaultProductsCsvReader : IProductsCsvReader {
public string[] ReadAllLines(string virtualPath) {
var productFilePath = HttpContext.Current.Server.MapPath(virtualPath);
String[] csvData = File.ReadAllLines(productFilePath);
return csvData;
}
}
Using DI just make sure that the abstraction and the implementation are registered with the composition root.
The use of HttpContext.Current makes you assume that the productFilePath is runtime data, but in fact it isn't. It is configuration value, because it _will not change during the lifetime of the application. You should instead inject this value into the constructor of the component that needs it.
That will obviously be a problem in case you use HttpContext.Current, but you can call HostingEnvironment.MapPath() instead; no HttpContext is required:
public class ProductReader
{
private readonly string path;
public ProductReader(string path) {
this.path = path;
}
public List<ProductItem> GetAllProductsFromCSV() { ... }
}
You can construct your class as follows:
string productCsvPath = HostingEnvironment.MapPath(#"~/CSV/products.csv");
var reader = new ProductReader(productCsvPath);
This doesn't solve the tight coupling with File, but I'll refer to Nkosi's excellent answer for the rest.

Unit Testing issue with Moq and Include (EF6)

I have done fair bit research and tried all sorts of different ways of getting the Test to pass but now i need some help.
I am trying to test the following repository method:
public class PortalsRepository : BaseRepository<PortalDomainRole>, IPortalsRepository
{
public PortalsRepository(IAuthDbContext context) : base(context)
{
}
public IEnumerable<PortalRole> GetRoles(string domainName)
{
return Set.Include(x => x.PortalDomain)
.Include(x => x.PortalRole)
.Where(x => x.PortalDomain.Name.ToLower() == domainName)
.Select(x => x.PortalRole)
.ToList();
}
}
The Context looks like:
public interface IAuthDbContext : IDbContextBase
{
}
public interface IDbContextBase
{
IDbSet<T> Set<T>() where T : class;
IEnumerable<DbValidationError> GetEntityValidationErrors();
int SaveChanges();
Task<int> SaveChangesAsync();
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
}
My Unit Test Set-up Looks like:
protected override void GivenThat()
{
var mockRolesSet = GetMockDbSet(PortalRoles().AsQueryable());
mockRolesSet.Setup(x => x.Include("PortalRole")).Returns(mockRolesSet.Object);
var mockDomainsSet = GetMockDbSet(PortalDomains().AsQueryable());
mockDomainsSet.Setup(x => x.Include("PortalDomain")).Returns(mockDomainsSet.Object);
var mockPortalDomanRolesSet = GetMockDbSet(PortalDomainRoles().AsQueryable());
mockPortalDomanRolesSet.Setup(x => x.Include("PortalRole")).Returns(mockPortalDomanRolesSet.Object);
mockPortalDomanRolesSet.Setup(x => x.Include("PortalDomain")).Returns(mockPortalDomanRolesSet.Object);
var customDbContextMock = new Mock<IAuthDbContext>();
customDbContextMock.Setup(x => x.Set<PortalRole>()).Returns(mockRolesSet.Object);
customDbContextMock.Setup(x => x.Set<PortalDomain>()).Returns(mockDomainsSet.Object);
customDbContextMock.Setup(x => x.Set<PortalDomainRole>()).Returns(mockPortalDomanRolesSet.Object);
ClassUnderTest = new PortalsRepository(customDbContextMock.Object);
}
My Unit Test Supporting Methods:
public List<PortalDomainRole> PortalDomainRoles()
{
var data = new List<PortalDomainRole>
{
new PortalDomainRole { PortalRoleId = 2, PortalDomainId = 1},
new PortalDomainRole { PortalRoleId = 1, PortalDomainId = 2},
new PortalDomainRole { PortalRoleId = 2, PortalDomainId = 2}
};
return data;
}
public List<PortalDomain> PortalDomains()
{
var data = new List<PortalDomain>
{
new PortalDomain { Name = "google.co.uk", PortalDomainId = 1 },
new PortalDomain { Name = "bbc.com", PortalDomainId = 2 }
};
return data;
}
public List<PortalRole> PortalRoles()
{
var data = new List<PortalRole>
{
new PortalRole {Name = "New Products", PortalRoleId = 1},
new PortalRole {Name = "Classic Products", PortalRoleId = 2}
};
return data;
}
When the unit test executes the method in question, i get:
System.NullReferenceException : Object reference not set to an instance of an object.
Most likely it does not know how to handle the nested include statements - i have followed many online questions and tutorials and now i am stuck.
My answer is probably a bit controversial, but in my experience, the best way to test your repository layer (or whatever you call the code that does the actual data access), is by having it actually call the database during testing.
When you are writing your unit test, you are assuming that Entity Framework works in a specific way. But sometimes it works in different ways than you expect, and thus a test may pass, even though the code doesn't work correctly.
Take this example, that illustrates the problem (the last EF version I worked with was version 4, but I assume that my statement is still true for EF6)
public class Foo {
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public bool Active {
get { return StartDate < DateTime.Now && EndDate > DateTime.Now }
}
}
public class FooRepository {
public IEnumerable<Foo> ActiveFoos { get { return DataContext.Foos.Where(x => x.Active) } }
}
Testing this FooRepository against a mocked data access will pass, but executing against a real database will throw an exception. That is because EF will try to create an SQL clause for the Where(x => x.Active), but because Active is not a field in the database, EF will have no idea how to translate the query to SQL.
So your unit test provides a false positive. Executing the tests against the database will make it fail, as it should.

Mock method of system-under-test with Moq

I have the following three methods in the CompanyApplication class (along with the supporting factories and services listed):
public ResultSet<CompanyDto> AddCompany(CompanyDto companyDto)
{
var result = new CompanyDto();
var company = new Company();
Mapper.Map(companyDto, company);
using (ITransaction t = _transactionFactory.Create())
{
company = _companyService.Add(company);
t.Commit();
}
Mapper.Map(company, result);
return new ResultSet<CompanyDto>(1, new[] { result });
}
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto)
{
var result = new CompanyContactDto();
var company = new Company();
var contact = new CompanyContact();
Mapper.Map(companyContactDto, contact);
using (ITransaction t = _transactionFactory.Create())
{
var contactCompanies = FindByIdJoin<Company, CompanyDto>(companyContactDto.CompanySK);
Mapper.Map(contactCompanies.Data.First(), company);
company.CompanyContacts.Add(contact);
company = _companyService.Update(company);
t.Commit();
}
Mapper.Map(contact, result);
return new ResultSet<CompanyContactDto>(1, new[] { result });
}
public ResultSet<T_DtoType> FindByIdJoin<T_DbType, T_DtoType>(long id)
{
IAbstractRepository<T_DbType> repository = EnsureRepository<T_DbType>();
T_DbType entity = repository.FindByIdJoin(id);
return (entity == null ? null : MapResultSetToDto<T_DbType, T_DtoType>(entity));
}
There are other objects in play here, which is why the FindByIdJoin has been made a separate method in the CompanyApplication class.
I have set up the testing class with some mocks and an instance of the CompanyApplication class:
private Mock<ICompanyRepository> _mockCompanyRepository;
private Mock<ICompanyDomain> _mockCompanyService;
private Mock<ITransactionFactory> _mockTransactionFactory;
private Mock<ITransaction> _mockTransaction;
private CompanyApplication _companyApplication;
[Setup]
public void SetUp()
{
_mockCompanyRepository = new Mock<ICompanyRepository>(MockBehavior.Strict);
_mockCompanyService = new Mock<ICompanyDomain>(MockBehavior.Strict);
_mockTransactionFactory = new Mock<ITransactionFactory>(MockBehavior.Strict);
_mockTransaction = new Mock<ITransaction>(MockBehavior.Strict);
_companyApplication = new CompanyApplication(
_mockCompanyRepository.Object,
_mockCompanyService.Object,
_mockTransactionFactory.Object);
}
I am successfully able to test the FindByIdJoin and AddCompany methods directly in Moq like this:
[Test]
public void CanFindCompanyByIdJoin()
{
var data = new Company {ObjectId = 1, Name = "Company1"};
_mockCompanyRepository.Setup(x => x.FindByIdJoin(It.Is<long>(arg => arg == data.ObjectId)))
.Returns(data);
var result = _companyApplication.FindByIdJoin<Company, CompanyDto>(data.ObjectId);
Assert.AreEqual(data.ObjectId, result.Data.First().ObjectId);
}
[Test]
public void CanAddCompany()
{
var data = new Company {ObjectId = 1, Name = "Company1"};
_mockCompanyService.Setup(x => x.Add(It.Is<Company>(arg => arg.ObjectId == data.ObjectId)))
.Returns(data);
_mockTransactionFactory.Setup(x => x.Create()).Returns(_mockTransaction.Object);
_mockTransaction.Setup(x => x.Commit());
_mockTransaction.Setup(x => x.Dispose());
var dto = new CompanyDto {ObjectId = 1, Name = "Company1"};
var result = _companyApplication.AddCompany(dto);
_mockCompanyService.Verify(t => t.Add(It.IsAny<Company>()));
}
Those two tests pass just fine. However, I'm having trouble coming up with a test for AddCompanyContact, because it calls FindByIdJoin as part of its flow, and that seems to be getting in the way.
Specifically, is there a way to mock var contactCompanies = FindByIdJoin<Company, CompanyDto>(companyContactDto.CompanySK) in a test for the AddCompanyContact method?
Thanks!
There is two alternatives that i see depending on the amount of work that you want to do.
Wrap that call into a object and instantiate it using a IOC container. This is the one that i feel would take the most effort if you are not using one already.
Turn that call into a Func and make a method without that parameter that does the call. This approach has the disadvantage that the top call will be untestable but will allow access to the rest of the method.
Example Below:
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto)
{
AddCompanyContact(CompanyContactDto, ()=>
{
return FindByIdJoin<Company, CompanyDto> companyContactDto.CompanySK);
}
}
public ResultSet<CompanyContactDto> AddCompanyContact(CompanyContactDto companyContactDto, Func<WhateverTheMethodReturns> findIdReplacement)
{
var result = new CompanyContactDto();
var company = new Company();
var contact = new CompanyContact();
Mapper.Map(companyContactDto, contact);
using (ITransaction t = _transactionFactory.Create())
{
var contactCompanies = findIdReplacement();
Mapper.Map(contactCompanies.Data.First(), company);
company.CompanyContacts.Add(contact);
company = _companyService.Update(company);
t.Commit();
}
Mapper.Map(contact, result);
return new ResultSet<CompanyContactDto>(1, new[] { result });
}
I was over complicating the problem... since AddCompanyContact calls FindByIdJoin, all I needed to do was mock the same interface that is used in FindByIdJoin.
Lesson learned: mock interfaces, not classes.

How to use Moq to satisfy a MEF import dependency for unit testing?

This is my interface
public interface IWork
{
string GetIdentifierForItem(Information information);
}
and my class
public class A : IWork
{
[ImportMany]
public IEnumerable<Lazy<IWindowType, IWindowTypeInfo>> WindowTypes { get; set; }
public string GetIdentifierForItem(Information information)
{
string identifier = null;
string name = information.TargetName;
// Iterating through the Windowtypes
// searching the 'Name' and then return its ID
foreach (var windowType in WindowTypes)
{
if (name == windowType.Metadata.Name)
{
identifier = windowType.Metadata.UniqueID;
break;
}
}
return identifier;
}
}
Problem : I want to unit test the method GetIdentifierForItem
Here is what I tried doing to solve it -
(1)Create a mock Lazy and set the values that it needs to return on property gets
var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>();
windowMock.Setup(foo => foo.Metadata.Name).Returns("Data");
windowMock.Setup(foo => foo.Metadata.UniqueID).Returns("someString");
(2)Create a window type list and the above mocked object and then set it to the created A object
var WindowTypesList = new List<IWindowType, IWindowTypeInfo>>();
WindowTypesList.Add(windowMock.Object);
A a = new A();
a.WindowTypes = WindowTypesList;
(3) Create the information mock
var InfoMock = new Mock<Information>();
InfoMock.Setup(foo => foo.TargetName).Returns("Data");
To put all of the above together as the unit test
[TestMethod]
public void GetIDTest()
{
var windowMock = new Mock<Lazy<IWindowType, IWindowTypeInfo>>();
windowMock.Setup(foo => foo.Metadata.Name).Returns("Data");
windowMock.Setup(foo => foo.Metadata.UniqueID).Returns("someString");
var WindowTypesList = new List<Lazy<IWindowType, IWindowTypeInfo>>();
WindowTypesList.Add(windowMock.Object);
A a = new A();
a.WindowTypes = WindowTypesList;
var InfoMock = new Mock<Information>();
InfoMock.Setup(foo => foo.TargetName).Returns("Data");
string expected = "someString"; // TODO: Initialize to an appropriate value
string actual;
actual = a.GetIdentifierForItem(InfoMock.Object);
Assert.AreEqual(expected, actual);
}
This unit test fails to execute and throws an exception 'TargetInvocationException' and veiwing the detail, it looks like I am doing something that I should not be doing.
But I am not sure how do it other way. I have read some of the links in the Quickstart guide of Moq. I know I am missing something. Can you help me by guiding how to unit test this?
This is how it may be done, after setting up the mocks
1) Creating a CompositionContainer, that holds the imports.
2) Adding Mocks to the container.
container.ComposeExportedValue(mock.Object);
3) Create an instance of tested class
4) Compose mocks to the import
container.ComposeParts(instance);
You don't need to Mock the Lazy<T,TMetadta>. It is flexible enough to work with your test. Instead, Mock the IWindowTypeInfo
[TestMethod]
public void GetIDTest()
{
var windowTypeInfoMock = new Mock<IWindowTypeInfo>();
windowTypeInfoMock.Setup(foo => foo.Name).Returns("Data");
windowTypeInfoMock.Setup(foo => foo.UniqueID).Returns("someString");
var lazyWindow =
new Lazy<IWindowType, IWindowTypeInfo>(windowTypeInfoMock.Object);
var WindowTypesList = new List<Lazy<IWindowType, IWindowTypeInfo>>();
WindowTypesList.Add(lazyWindow);
var a = new A();
a.WindowTypes = WindowTypesList;
var InfoMock = new Mock<Information>();
InfoMock.Setup(foo => foo.TargetName).Returns("Data");
string expected = "someString";
string actual;
actual = a.GetIdentifierForItem(InfoMock.Object);
Assert.AreEqual(expected, actual);
}
Your test passes on my machine with only small modifications, you do not need to use a composition container for this test.

Categories

Resources