ReSharper dotcover showing 0% coverage despite tests running through code - c#

I'm assuming this is an error on my part but I can't figure out why ReSharper dotcover is showing my test coverage of certain queries (and commands too) as 0%.
So I have a .NET Core CQRS API that is made up of a lot of EF Core LINQ. Below is a simple example of one of my queries's main execute method (I left out the DI constructor but I'm sure you git the idea):
public bool Execute(SelectIsReportRequested query)
{
var context = _clientDatabase.GetContext(query.DatabaseId);
var result = (from a in context.Assessments
join r in context.Registrations on a.AssessmentId equals r.AssessmentId
where a.PublicId == query.ResponseId
select r.ReportRequested).SingleOrDefault();
return result == 1;
}
Then I have the following test that mocks the various bits and runs the query:
[TestMethod]
public void It_should_return_true_if_a_report_has_been_requested_for_the_givenassessment()
{
const int assessmentId = 1;
var responseId = Guid.NewGuid();
var mockRepository = new Mock<ICViewClientContext>();
var assessments = new List<Assessments>
{
new Assessments { AssessmentId = assessmentId, PublicId = responseId },
};
var registrations = new List<Registrations>
{
new Registrations { AssessmentId = assessmentId, ReportRequested = 1 },
};
mockRepository.Setup(x => x.Registrations).Returns(registrations.AsDbSetMock().Object);
mockRepository.Setup(x => x.Assessments).Returns(assessments.AsDbSetMock().Object);
var mockClientDatabase = new Mock<IClientDatabase>();
mockClientDatabase.Setup(x => x.GetContext(1)).Returns(mockRepository.Object);
var query = new Queries.Assessments.SelectIsReportRequested(2, responseId);
var handler = new Queries.Assessments.SelectIsReportRequestedHandler(mockClientDatabase.Object);
var result = handler.Execute(query);
Assert.AreEqual(true, result);
}
The tests passes (and will also fail if I break the logic in the LINQ) or any other logic in the code.
However, running dotcover runs the test, passes it but says that none of it is covered.
I would love to know why because it's really driving me insane and worries me that I've done something completely wrong!

So I think through blind luck I have been able to solve my issue and wanted to post what I did just in case it helps anyone else.
Whilst trying to get the logs to submit to JetBrains I did the following:
In ReSharper | Options… | dotCover | General, disabled 'Use preloaded Unit Test runners'
Saved settings
Went back and enabled 'Use preloaded Unit Test runners'
Saved settings
Then I re-ran dotcover and suddenly all my test coverage was shown and all my test cover code highlighting was shown correctly.
I've sent a message back to JetBrains and if they give me any info as to why that solved it I'll post that too.

I had a similar issue when dotCover didn't recognize some of the unit tests.
I was able to resolve it by removing Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll from Test Project references and installing MSTest.TestFramework and MSTest.TestAdapter nuget packages.

Related

Testing Ldapconnection Sendrequest

I am using Ldapconnection.Sendrequest because I am running on Linux, so I can only use classes from the System.DirectoryServices.Protocols namespace.
The code works perfectly well against a live Active Directory, but here is an example anyway.
// retrieves the distinguishedname for all groups, starting from dc=test,dc=local
var request = new SearchRequest("dc=test,dc=local", "(Objectclass=group)", "distinguishedname");
var searchResponse = ldapConnection.SendRequest(request) as SearchResponse;
My question is, how can this be unit tested? I would like to unit test it because a different searchResponse will cause a different path to be taken through code.
I have tried mocking SearchResponse: (How to create an instance of SearchResponse class (which has no public constructors)?)
var ctors = typeof (SearchResponse).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
var neededCtor = ctors.First(
ctor =>
ctor.GetParameters().Count() == 5);
SearchResponse response = neededCtor.Invoke(new object[]
{
"distinguishedName",
null, // System.DirectoryServices.Protocols.DirectoryControl[]
null, // System.DirectoryServices.Protocols.ResultCode
errorMessage,
null // System.Uri[]
}) as SearchResponse;
return response;
But I cannot find a way to mock SearchResponse.Entries, as SearchResultEntryCollection and SearchResultEntry are (seemingly) unmockable. It's as though the dotnet team has gone out of its way to make this area completely unmockable.
I'm new to using LdapConnection (previously I could use the AccountManagement class, as I was running in Windows), so maybe I shouldn't be using LdapConnection in the first place?
Equally, I'd be open to running the AD tests in memory, as I would for database access, but I cannot find a way to do so.
Many thanks for you help,
Dan

MVC4 Unit test NSubstitute Could not find a call to return from

I have a MVC4 web application I'm unit testing right now. It uses entity framework for the database portion. I'm using NSubstitute to mock the database. This code is basically copied and pasted from another site which works fine, so I hope I'm just missing something super simple.
Thanks in advance!
Applications table in SQL:
AppID | ApplicationName
----------------------------
1 | MyCoolApplication
2 | MyOtherApplication
Entity created the Application class:
public class Application
{
public int AppID { get; set; }
public string ApplicationName { get; set; }
}
The mock section of the unit test looks like this:
var mockDb = Substitute.For<MyCoolApplicationsEntities>();
var applications = new List<Application>
{
new Application {AppID = 1, ApplicationName = "MyCoolApplication"},
new Application {AppID = 2, ApplicationName = "MyOtherApplication"},
};
var mockApplicationSet = Substitute.For<IDbSet<Application>, DbSet<Application>>();
mockApplicationSet.Provider.Returns(applications.AsQueryable().Provider);
mockApplicationSet.Expression.Returns(applications.AsQueryable().Expression);
mockApplicationSet.ElementType.Returns(applications.AsQueryable().ElementType);
mockApplicationSet.GetEnumerator().Returns(applications.AsQueryable().GetEnumerator());
mockApplicationSet.When(q => q.Add(Arg.Any<Application>()))
.Do(q => applications.Add(q.Arg<Application>()));
mockApplicationSet.When(q => q.Remove(Arg.Any<Application>()))
.Do(q => applications.Remove(q.Arg<Application>()));
mockDb.Applications.Returns(mockApplicationSet); //This is the line creating the error
The full error is:
Test method
MyProjectName.Controllers.MyControllerTest.TestOfSectionImTesting
threw exception:
NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException:
Could not find a call to return from.
Make sure you called Returns() after calling your substitute (for
example: mySub.SomeMethod().Returns(value)), and that you are not
configuring other substitutes within Returns() (for example, avoid
this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that
the call to your substitute was on a virtual/abstract member. Return
values cannot be configured for non-virtual/non-abstract members.
Correct use:
mySub.SomeMethod().Returns(returnValue);
Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub());
Instead try:
var returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);
But that doesn't work in my environment because Applications isn't a method. Like I said, this works fine in another site of mine, so it's got to be something basic I'm missing. Nothing I've found online has been helpful with my particular case. I updated to the newest version of NSubstitute and I uninstalled/reinstalled, but still have got nothing.
Again, thanks in advance!
NSubstitute can not mock non-virtual members. (There are quite a few caveats to substituting for classes.)
MyCoolApplicationsEntities.Applications will need to be virtual for .Returns() to work.
Here's what ended up working:
var context = Substitute.For<MyCoolApplicationsEntities>();
var applications = new List<Application>
{
new Application {AppID = 1, ApplicationName = "MyCoolApplication"}
};
var mockApplications = Substitute.For<DbSet<Application>, IQueryable<Application>>();
((IQueryable<Application>)mockApplications).Provider.Returns(applications.AsQueryable().Provider);
((IQueryable<Application>)mockApplications).Expression.Returns(applications.AsQueryable().Expression);
((IQueryable<Application>)mockApplications).ElementType.Returns(applications.AsQueryable().ElementType);
((IQueryable<Application>)mockApplications).GetEnumerator().Returns(applications.AsQueryable().GetEnumerator());
mockApplications.When(q => q.Add(Arg.Any<Application>()))
.Do(q => applications.Add(q.Arg<Application>()));
mockApplications.When(q => q.Remove(Arg.Any<Application>()))
.Do(q => applications.Remove(q.Arg<Application>()));
context.Applications = mockApplications;
I can't see you classes but you need to create interfaces with virtual members and have your code call the class by the interface, then you will be able to mock out the class.

Add Test Case to ITestSuiteBase in TFS API

I'm working with the TFS API and have run into a problem with ITestSuiteBase and IRequirementTestSuite. I've mananged to easily create a new test case within a IStaticTestSuite:
IStaticTestSuite workingSuite = this.WorkingSuite as IStaticTestSuite;
testCase = CreateTestCase(this.TestProject, tci.Title, tci.Description);
workingSuite.Entries.Add(testCase);
this.Plan.Save();
However, this solution doesn't work for requirements test suites or ITestSuiteBase. The method that I would assume would work is:
ITestcase testCase = null;
testCase = CreateTestCase(this.TestProject, tci.Title, tci.Description);
this.WorkingSuite.AllTestCases.Add(testCase);
this.WorkingSuite.TestCases.Add(testCase);
this.Plan.Save();
But this method doesn't actually add the test case to the suite. It does, however, add the test case to the plan. I can query the created test case but it doesn't show up in the suite as expected - even immediately in the code afterwards. Refreshing the working suite has no benefit.
Additional code included below:
public static ITestCase CreateTestCase(ITestManagementTeamProject project, string title, string desc = "", TeamFoundationIdentity owner = null)
{
// Create a test case.
ITestCase testCase = project.TestCases.Create();
testCase.Owner = owner;
testCase.Title = title;
testCase.Description = desc;
testCase.Save();
return testCase;
}
Has anyone been able to successfully add a test case to a requirements test suite or a ITestSuiteBase?
Giulio's link proved to be the best way to do this
testCase = CreateTestCase(this.TestProject, tci.Title, tci.Description);
if (this.BaseWorkingSuite is IRequirementTestSuite)
TFS_API.AddTestCaseToRequirementSuite(this.BaseWorkingSuite as IRequirementTestSuite, testCase);
else if (this.BaseWorkingSuite is IStaticTestSuite)
(this.BaseWorkingSuite as IStaticTestSuite).Entries.Add(testCase);
this.Plan.Save();
And the important method:
public static void AddTestCaseToRequirementSuite(IRequirementTestSuite reqSuite, ITestCase testCase)
{
WorkItemStore store = reqSuite.Project.WitProject.Store;
WorkItem tfsRequirement = store.GetWorkItem(reqSuite.RequirementId);
tfsRequirement.Links.Add(new RelatedLink(store.WorkItemLinkTypes.LinkTypeEnds["Tested By"], testCase.WorkItem.Id));
tfsRequirement.Save();
reqSuite.Repopulate();
}
This is expected.
Static Test Suites are ... static while Requirement-based Test Suites are dynamic. The relationship between a Test Case and a Requirement is determined by the presence of a proper Tests/Tested By Work Item Link, so you need to add such a link.
For sample code see Not able to add test cases to type of IRequirementTestSuite.
Small note: you cannot duplicate links, so you may have to check for existence if the Test Case is not new.

How can I programmatically checkin code in TFS with policy override?

I'm trying to checkin code from a c# program in a part of TFS repository which will trigger a gated checkin build and also a continuous integration build.
This is my code so far:
public static void Checkin(string path, string comment)
{
var wsInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(wsInfo.ServerUri);
tfs.Connect(ConnectOptions.None);
var vcs = tfs.GetService<VersionControlServer>();
var ws = vcs.GetWorkspace(path);
var fullPath = Path.GetFullPath(path);
var change = ws.GetPendingChangesEnumerable().Where(p => p.LocalItem == fullPath).ToArray();
ws.CheckIn(change.ToArray(), comment);
tfs.Dispose();
}
what is basically happening is that I get a GatedCheckinException say that there is an affected build defintion.
I would like to do the checkin with the commonly known bypass to avoid triggering the gated checkin. I've been struggling with the altenate Checkin functions without success.
Any idea?
UPDATE:
Thanks Aghilas Yakoub for the link.
For completeness, here is the code to do the checkin with override that worked for me:
var wip = new WorkspaceCheckInParameters(change, comment)
{
OverrideGatedCheckIn = ((CheckInOptions2)vcs.SupportedFeatures & CheckInOptions2.OverrideGatedCheckIn) == CheckInOptions2.OverrideGatedCheckIn,
PolicyOverride = new PolicyOverrideInfo("Check-in from the build.", null)
};
ws.CheckIn(wip);
I suggest you this sample of code http://blogs.infosupport.com/override-gated-check-in-using-the-tfs-api/

Microsoft Shims Can't Debug Method Under Test

I have a test method that is fine when I run it but fails with an exception when debugged.
Here is the tested method and output from VS Test Runner below. The exception is coming from ShimsContext.Create()
Info: VS 2012 Permium Update2
[TestMethod]
public void TestResolveDateWithShim()
{
using (ShimsContext.Create())
{
// arrange
DateTime someTestTime = new DateTime(2013, 1, 14);
Fakes.ShimDateHelper.PreviousOrCurrentQuarterEndDateTime =
time => someTestTime;
var appCache = new Fakes.StubIAppCache();
var series = new StubISeries();
series.KeyGet = () => SeriesKey.MyKey;
// act
Report report = new Report(SeriesKey.MyKey, appCache);
DateTime resolvedDate = report.ResolveDate(series, DateTime.Now);
// assert
Assert.AreEqual(someTestTime, someTestTime);
}
I solved it. It was resharper that was causing the problems. In the resharper tab under options. Under Tools->Unit Testing -> MSTest I unchecked the 'Use Legacy Runner' checkbox. Now it worksd and I can still use resharper to help me test. I I jsut disable all test options in resharper it works as well but I want some options from resharper because they are very helpful.

Categories

Resources