In the following code. The Assert.Equal(...) of the Callback() is never called?
var test = "Test";
var command = new MyCommand { V = test };
var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(p))
.Callback<P>(x => Assert.Equal(x.Value, test)); // break point on Assert.Equal not hit
var sut = new C(mock.Object);
var result = await sut.M(command);
You have:
.Setup(x => x.Save(p))
but are you sure the P used in your SUT is "equal to" just that p? Instead you could do:
.Setup(x => x.Save(It.IsAny<P>()))
and in that case the set-up (and call-back) would apply to any argument.
Related
I have the test below and am using standard mocking on a DbSet/Context. When the test runs it fails as it states that "The source IQueryable doesn't implement IAsyncEnumerable Team. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations".
public async Task Get_team_name_with_valid_search_term_returns_team_names()
{
// Arrange
var data = new List<Team>
{
new Team {Name = "Leeds"},
new Team {Name = "Glasgow"}
}.AsQueryable();
var mockSet = new Mock<DbSet<Team>>();
mockSet.As<IQueryable<Team>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Team>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Team>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Team>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<RadContext>();
mockContext.Setup(c => c.Team).Returns(mockSet.Object);
var service = new ITeamSearchService(mockContext.Object);
// Act
var result = await service.GetTeamName("Gla");
// Assert
}
The service itself is quite simple
public async Task<List<SearchTeamResponse>> GetTeamName(string searchTerm)
{
if (searchTerm == null)
{
throw new ArgumentNullException(nameof(searchTerm));
}
var query = await _radContext.Team.Where(x => x.Name.StartsWith(searchTerm))
.OrderBy(x => x.Name)
.ToListAsync();
var json = JsonConvert.SerializeObject(query);
var result = JsonConvert.DeserializeObject<List<SearchTeamResponse>>(json);
return result;
}
I am writing an unit test to test my EF project . while doing the test I am getting an error while configuraing the fake for the DBSet.
My Call stack is
System.NotImplementedException
The member 'IQueryable.ElementType' has not been implemented on type
'DbSet`1Proxy_10' which inherits from 'DbSet`1'. Test doubles for 'DbSet`1'
must provide implementations of methods and properties that are used.
at
system.Data.Entity.Infrastructure.DbQuery`1.GetInternalQueryWithCheck(String
memberName)
at
My Unit Test Code is - I had added a mapping data
var socMappingList = new List<DFC_SocMappings>()
{
new DFC_SocMappings()
{
JobProfile = "Police Officer",
ONetCode = "111-00.01",
QualityRating = 4,
SocCode = "1120"
},
new DFC_SocMappings()
{
JobProfile = "Police Officer",
ONetCode = "111-00.02",
QualityRating = 4,
SocCode = "1121"
},
};
//Arrange
var applicationLogger = A.Fake<IApplicationLogger>();
var fakeIQueryable = new List<DFC_SocMappings>().AsQueryable();
var context = A.Fake<IObjectContextFactory<OnetRepositoryDbContext>>();
// var fakeDbSet = A.Fake<DbSet<DFC_SocMappings>>();
IMapper iMapper = new AutoMapper.Mapper(new MapperConfiguration(cfg => cfg.AddProfile(new SkillsFrameworkMapper())));
var fakeDbSet = A.Fake<DbSet<DFC_SocMappings>>((d => d.Implements(typeof(IQueryable<DFC_SocMappings>)).Implements(typeof(IDbAsyncEnumerable<DFC_SocMappings>)))).SetupData(socMappingList);
A.CallTo(() => context.GetContext().DFC_SocMappings).Returns(fakeDbSet);
var ct = A.Fake<OnetRepository>(op => op.WithArgumentsForConstructor(new object[] { context, iMapper, applicationLogger }));
//Act
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).Provider).Returns(fakeIQueryable.Provider);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).Expression).Returns(fakeIQueryable.Expression);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).ElementType).Returns(fakeIQueryable.ElementType);
A.CallTo(() => ((IQueryable<DFC_SocMappings>)fakeDbSet).GetEnumerator()).Returns(fakeIQueryable.GetEnumerator());
//Assert
var onetRespository = new OnetRepository(context, iMapper, applicationLogger);
var response = await onetRespository.GetAllSocMappingsAsync<DfcOnetSocMappings>();
var res = response; // failing while reading the data
A.CallTo(() => context.GetContext().Set<DFC_SocMappings>()).MustHaveHappened();
response.Should().NotBeNull();
response.Should().BeSameAs(socMappings);
onetRespository.Dispose();
Can someone tell what mistake I am doing.
I try to write test for my Hub method, but I don't know as because there is no documentation or code examples for current (1.0.0-alpha2-final) version of SignalR. There is my code:
[Fact]
public void SaveVisitorInfoTest()
{
//Arrange
var chatHub = new ChatHub();
var mockClients = new Mock<IHubClients>();
chatHub.Clients = mockClients.Object;
dynamic groups = new ExpandoObject();
var groupName = "SomeConversation";
string actualName = null;
string expectedName = "someName";
groups.SendVisitorInfo = new Action<string, string>(n => {
actualName = n;
});
mockClients.Setup(_ => _.Group(groupName)).Returns(groups);
//Act
chatHub.Clients.Group(groupName).InvokeAsync("SendVisitorInfo", expectedName);
// Assert
Assert.Equal(expectedName, actualName);
}
Visual Studio generates next error message while running the test:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException :
'Moq.Language.Flow.ISetup'
does not contain a definition for 'Returns'
In old versions mock clients and groups creation looks like this:
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
dynamic groups = new ExpandoObject();
groups.SendVisitorInfo = new Action<string, string>(n => {
actualName = n;
});
mockClients.Setup(_ => _.Group(groupName)).Returns((ExpandoObject)groups)
But I can't use IHubCallerConnectionContext now, so I tried:
var mockClients = new Mock<IHubClients>();
but i don't know how to create mock groups in this case
Sorry for my terrible english
I don't have enough rep to comment but this link was as good as I could find for testing AspNetCore.SignalR v1.0.2:
https://buildingsteps.wordpress.com/2018/06/12/testing-signalr-hubs-in-asp-net-core-2-1/
It's still pretty ugly.
What I want to be able to do is
public Task DoCallback(IHubContext<MyHub> hubContext)
{
var clients = m_hubContext.Clients as IHubClients<IMyHubClient>;
clients.Client( "one").myCallback("Hi!");
}
Then mock out like:
var hubContext = new Mock<IHubContext<MyHub>>();
hubContext.Setup( h => h.Clients )
.Returns( m_hubClients.Object );
var hubClients = new Mock<IHubClients>();
var clientCallbacks = new Mock<IMyHubClient>();
hubClients.As<IHubClients<IMyHubClient>>()
.Setup( c => c.Client( "one" ) )
.Returns( clientCallbacks.Object );
clientCallbacks.Setup( c => c.myCallback( It.IsAny<string>() ) )
.Callback( ( stringp ) =>
{
...etc...
Hopefully in a future release...
I am attempting to write a test case that will confirm that the value of a parameter passed into the method under test was used to invoke a delegate function that is passed as an argument to a method on a mocked service. The example below illustrates what I am doing:
The method under test:
public IList<IResultData> GetResultData(int id)
{
Func<IExternalInterface, List<ExternalData> getDataMethod = client => client.GetExternalData(id);
List<ExternalData> externalDataList = serviceClient.ExecuteService(getDataMethod, "GetExternalData");
var result = new List<ResultData>();
//Some code to convert externalDataList into an IList<IResultData>
return result;
}
The test method:
[TestMethod]
public void TestMethodCall()
{
var mockServiceClient = MockRepository.GenerateMock<IServiceClient>();
mockServiceClient.Expect(x => x.ExecuteService(
Arg<Func<IExternalInterface, List<ExternalData>>.Is.NotNull,
Arg<string>.Is.Equal("GetExternalData")));
var myClass = new MyClass(mockServiceClient);
var result = myClass.GetResultData(3);
//Some assertions that result is as expected.
}
Is there a way to assert that the function passed into the Execute method is being passed the id of 3 from the test method's call to GetResultData()? The service being mocked is in a library not under my control so I can't change it's signature.
The following pattern will allow you to assert the lambda:
[TestMethod]
public void TestMethod1()
{
var wasCalled = false;
var fakeService = MockRepository.GenerateStub<IExternalInterface>();
fakeService.Stub(x => x.GetExternalData(1))
.Return(new List<ExternalData>() {new ExternalData() {Id = 1}});
fakeService.Stub(service => service.ExecuteService(Arg<Func<IExternalInterface,
List<ExternalData>>>.Is.Anything, Arg<string>.Is.Anything))
.WhenCalled(invocation =>
{
wasCalled = true;
var func = (Func<IExternalInterface, List<ExternalData>>) invocation.Arguments[0];
var res = func(fakeService);
//
// Assert here the "res"
//
}).Return(null);
var target = new MyClass(fakeService);
target.GetResultData(1);
Assert. IsTrue(wasCalled);
}
However based you the code you've provided a better solution would be to use Do method as the following:
[TestMethod]
public void TestMethod1()
{
var fakeService = MockRepository.GenerateStub<IExternalInterface>();
fakeService.Stub(x => x.GetExternalData(1)).Return(new List<ExternalData>() {new ExternalData() {Id = 1}});
fakeService.Stub(service => service.ExecuteService(Arg<Func<IExternalInterface,
List<ExternalData>>>.Is.Anything, Arg<string>.Is.Anything))
.Do(new Func<Func<IExternalInterface, List<ExternalData>>, string, List<ExternalData>>((func, str)=>func(fakeService)));
var target = new MyClass(fakeService);
var result = target.GetResultData(1);
//
// Assert here the "result"
//
}
I need to make changes to a legacy class with no tests so I have started by writing a test, however the mocking (using Moq) isn't working properly.
This my test
[Test]
public void CorrectlyCopiesToLightningWhenNoLocationsExist()
{
// arrange
long orgId = Id64.NewId();
var data = LightningMapLocationsHelperTestData.ForNormalCopy(orgId);
var organisation = new Group
{
GroupId = orgId,
Name = "Test Organisation",
Type = GroupType.OrganisationGroup
};
var groupRepo = new Mock<IGroupRepository>();
groupRepo.Setup(r => r.GetGroup(orgId)).Returns(organisation);
var orgRepo = Mock.Of<IOrganisationRepository>(o => o.LightningLocationsEnabledFor(orgId));
var mapLocationRepo = new Mock<IMapLocationRepository>();
mapLocationRepo.Setup(r => r.OrganisationRepository).Returns(orgRepo);
mapLocationRepo
.Setup(r => r.GetMapLocationsByGroupIds(orgId, It.IsAny<IEnumerable<long>>(), true, true))
.Returns(data.InitialDatabaseLocations);
var lightningMapLocationRepo = new Mock<ILightningMapLocationRepository>();
lightningMapLocationRepo
.Setup(r => r.LocationsById(orgId, data.InitialLightningLocations.Select(l => l.LocationId)))
.Returns(data.InitialLightningLocations);
lightningMapLocationRepo
.Setup(r => r.AddLocations(It.IsAny<List<Location>>()))
.Callback((List<Location> locations) => data.InitialLightningLocations.AddRange(locations));
var infoMessages = new List<string>();
var errorMessages = new List<string>();
var helper = new LightningMapLocationsHelper(
(string s, object[] args) => infoMessages.Add(string.Format(s, args)),
(string s, object[] args) => errorMessages.Add(string.Format(s, args)));
List<CopyFailure> copyFailures;
// act
bool success = helper.CopyLocationsForOrganisation(orgId, 10, out copyFailures);
// assert
success.ShouldBeTrue();
(errorMessages?.Count ?? 0).ShouldBe(0);
data.InitialLightningLocations.Count.ShouldBe(data.ExpectedLightningLocations.Count);
}
Inside LightningMapLocationsHelper is the following method
private Group GetValidOrganisationGroup(long groupId)
{
var organisation = (new GroupRepository()).GetGroup(groupId);
if (organisation != null && organisation.Type == GroupType.OrganisationGroup) return organisation;
LogErrorMessage("Invalid groupId: {0}. Ignoring...", groupId);
return null;
}
that when called is using an actual instance of GroupRepository rather than the groupRepo mock set up in the test, thus causing the test to fail. As GroupRepository implements IGroupRepository I expected this to work.
public class GroupRepository : IGroupRepository {…}
Perhaps I am misunderstanding how mocking works. Can someone offer some insight to help me understand why this doesn't work, and how I can fix it? Do I have to pass the mocked classes in?