.netcore unit testing not running properly - c#

I have created some unit tests for a simple c#/dotnet-core console application.
I have created the reference on the testing project but for some reason the "dotnet test" cmd is still reporting the following error:
UnitTest1.cs(12,25): error CS0103: The name 'LinkChecker' does not
exist in the current context
[/Users/med.bensalem/Desktop/dotnet-projects/checklinksTests/checklinksTests.csproj]
UnitTest1.cs(19,25): error CS0103: The name 'LinkChecker' does not
exist in the current context
[/Users/med.bensalem/Desktop/dotnet-projects/checklinksTests/checklinksTests.csproj]
Project structure:
.
├── checklinksTests
│ ├── UnitTest1.cs
│ ├── checklinksTests.csproj
└── checklinksconsole
└── code
├── LinkChecker.cs
├── Program.cs
└── checklinksconsole.csproj
Please find below the code I project source code:
Main application - checklinksconsole:
checklinksconsole.csproj - file:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
</ItemGroup>
</Project>
Program.cs - file:
using System;
using System.Linq;
using System.Net.Http;
namespace checklinksconsole
{
class Program
{
static void Main(string[] args)
{
var site = "https://www.google.com";
var client = new HttpClient();
var body = client.GetStringAsync(site);
Console.WriteLine(body.Result);
Console.WriteLine();
Console.WriteLine("Links:");
var links = LinkChecker.GetLinks(body.Result);
links.ToList().ForEach(Console.WriteLine);
}
}
}
LinkChecker.cs - file:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using HtmlAgilityPack;
namespace checklinksconsole
{
public class LinkChecker
{
public static IEnumerable<string> GetLinks(string page)
{
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(page);
var links = htmlDocument.DocumentNode.SelectNodes("//a[#href]")
.Select(n => n.GetAttributeValue("href", string.Empty))
.Where(l => !String.IsNullOrEmpty(l))
.Where(l => l.StartsWith("http"));
return links;
}
}
}
Unit testing - checklinksTests:
checklinksTests.csproj - file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\checklinksconsole\code\checklinksconsole.csproj" />
</ItemGroup>
</Project>
UnitTest1.cs - file:
using System;
using Xunit;
namespace checklinksTests
{
public class UnitTest1
{
[Fact]
public void WithoutHTTPAtTheStartOfTheLink_NoLinks()
{
var links = LinkChecker.GetLinks("<a href=\"google.com\" />");
Assert.Equal(links.Count(),0);
}
[Fact]
public void WithHTTPAtTheStartOfTheLink_LinkParses()
{
var links = LinkChecker.GetLinks("<a href=\"http://google.com\" />");
Assert.Equal(links.Count(),1);
Assert.Equal(links.First(), "google.com");
}
}
}
Any idea on what is wring with my code.
Thank you

You’re missing a using checklinksconsole; directive at the top of your test class to bring the LinkChecker class into scope.

Related

Unable to consume MSBuild properties in service resolving source generator

I use Injectio and I'm having issue resolving the MSBuild properties. These are also documented in the source generator cookbook.
I made a simple Console application as a minimal reproducible example and initially added Injectio as a NuGet package which I then replaced with local Injectio project reference, so that it helps me debug the MSBuild properties and see what's wrong, more specifically this line of code:
public void Initialize(IncrementalGeneratorInitializationContext context)
{
if (!Debugger.IsAttached)
{
Debugger.Launch();
}
...
It ignores the property group below in my .csproj file. Why? Do I have to do CompilerVisibleProperty or something? This was also documented in the Injectio README, scroll down to the bottom.
<PropertyGroup>
<InjectioName>Library</InjectioName>
</PropertyGroup>
All this property is supposed to do is let me use custom name for the registrator instead of services.AddTest(), e.g. in this case it should be services.AddLibrary().
.ConfigureServices(services =>
{
services.AddTest(); // Expected: => services.AddLibrary()
})
Test.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<InjectioName>Library</InjectioName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Injectio" Version="1.0.33" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
</ItemGroup>
</Project>
Program.cs
using Injectio.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureServices(services =>
{
services.AddTest();
})
.ConfigureLogging(x => x.AddConsole())
.UseConsoleLifetime()
.Build();
await host.RunAsync();
[RegisterSingleton(ServiceType = typeof(IHostedService))]
internal sealed class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly PeriodicTimer _timer = new(TimeSpan.FromSeconds(10));
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (await _timer.WaitForNextTickAsync(stoppingToken))
{
try
{
_logger.LogInformation("Worker running at: {Time}", DateTimeOffset.Now);
}
catch (Exception ex)
{
_logger.LogError(ex, "Oh, no! Something bad happened");
}
}
}
}
It seems like I had to add CompilerVisibleProperty to the .csproj file, so it recognizes the MSBuild property.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<PropertyGroup>
<InjectioName>Library</InjectioName>
</PropertyGroup>
<ItemGroup>
<CompilerVisibleProperty Include="InjectioName" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Injectio" Version="1.0.33" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
</ItemGroup>
</Project>

xUnit MessageSink for Collection Fixture does not generate output

I'm trying to add diagnostic output to my xUnit tests. For this, I'm using a combination of Collection Fixture and IMessageSink. This is my code:
using System;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace MessageSink
{
[Collection("My collection")]
public class UnitTest1
{
private readonly MyCollectionFixture _fixture;
public UnitTest1(MyCollectionFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void Test1()
{
_fixture.Sink.OnMessage(new DiagnosticMessage("Hello World"));
}
}
public class MyCollectionFixture : IDisposable
{
public MyCollectionFixture(IMessageSink sink)
{
Sink = sink;
}
public IMessageSink Sink { get; }
public void Dispose()
{
}
}
[CollectionDefinition("My collection")]
public class MyCollection : ICollectionFixture<MyCollectionFixture>
{
}
}
Within the test project, I've created the following xunit.runner.json:
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"diagnosticMessages": true
}
And this is my project configuration:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Include="xunit.runner.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
I'd expect Hello World within the output of the test runner - but it is empty.
I (hopefully 🤞🏻) followed the docs in the correct way:
Shared Context between Tests
Capturing Output
Configuration Files
What am I doing wrong?
Thanks and cheers 👋🏻
You'll need to extend IClassFixture<MyCollectionFixture> to get that working for diagnostic messages.
For in-test messages, try using ITestOutputHelper which you can pass in into your test class along with MyCollectionFixture.
Check docs out: https://xunit.net/docs/capturing-output

Azure durable function orchestration client cannot be found when the DurableTask nuget package is upgraded to version 2.0.0

Have a queue-triggered function defined as the following example:
public async Task OrchestratorAsync(
[QueueTrigger("my-queue", Connection = "")]string payload,
[OrchestrationClient] DurableOrchestrationClient orchestrationClient)
{
//Do something
}
The csproj file looks like the following details and it compiles successfully:
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="1.8.2" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.10" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
</ItemGroup>
</project>
When I upgrade Microsoft.Azure.WebJobs.Extensions.DurableTask to version 2.0.0 the compiler throws error on not being able to find OrchestrationClient and DurableOrchestrationClient. So we're stuck with version 1.8.2! What's the solution for this issue?
Note: This issue is quite reproducible by VS 2019. Have it scaffold a Function project, the create another function as a durable orchestrator, tweak the csproj file and bump up the DurableTask nuget package version to 2.0.0 from the default 1.8.2.
I have reproduce your error, and I solved this problem.
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace _11111fc
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
[DurableClient] IDurableOrchestrationClient orchestrationClient)
{
var outputs = new List<string>();
// Replace "hello" with the name of your Durable Activity Function.
outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "Tokyo"));
outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "Seattle"));
outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "London"));
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}
[FunctionName("Function1_Hello")]
public static string SayHello([ActivityTrigger] string name, ILogger log)
{
log.LogInformation($"Saying hello to {name}.");
return $"Hello {name}!";
}
[FunctionName("Function1_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
[DurableClient]IDurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("Function1", null);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
}
Solution:
Change [OrchestrationClient] to [DurableClient]. Have a look of this.
Please take care of the breaking changes in Durable Functions v2.0.0-beta2 Release, the OrchestrationClient has been renamed.
Things works fine on my side. Please have a try on your side.

Where do I find TestContext.AddResultFile()?

I am having trouble referencing the documented method AddResultFile() on the TestContext class, allegedly found in the Microsoft.VisualStudio.TestTools.UnitTesting package/namespace.
This is my package list:
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="Selenium.Support" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
<PackageReference Include="specflow" Version="3.0.199" />
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.0.199" />
<PackageReference Include="SpecFlow.MsTest" Version="3.0.199" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0-beta4" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0-beta4" />
This is (a part of) my test (step definition - it's SpecFlow) class:
using System;
using System.IO;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using TechTalk.SpecFlow;
using XunitTestLib.Drivers;
using XunitTestLib.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace XunitTestLib.StepDefinitions
{
[Binding]
public class BrowserSteps : BrowserDriver
{
public IWebElement CurrentElement { get; set; }
public TestContext TestContext { get; set; }
public BrowserSteps(TestContext tcontext)
{
this.TestContext = tcontext;
}
[Given(#"I navigate to (.*)")]
[When(#"I navigate to (.*)")]
[Then(#"I navigate to (.*)")]
public void INavigateTo_(string url)
{
Browser.Navigate().GoToUrl(url);
}
// ***Numerous methods for specflow/selenium-based testing***
[Given(#"I take a screenshot")]
[When(#"I take a screenshot")]
[Then(#"I take a screenshot")]
public void ITakeAScreenshot()
{
var sep = Path.DirectorySeparatorChar;
var time = DateTime.Now.ToString("yyyy-MM-dd_HH_mm_SS_") + DateTime.Now.Ticks;
var path = $#"{Directory.GetCurrentDirectory()}{sep}{time}.png";
Browser
.GetScreenshot()
.SaveAsFile(path);
TestContext.AddResultFile(path); // THIS METHOD NOT FOUND
}
}
}
How do I find and use the AddResultFile() method? I assume I'm missing a reference...?
There was a bug in MSTest.TestFramework package reported here:
https://github.com/Microsoft/testfx/issues/394
It is resolved 4 days ago from today in a pull request :
https://github.com/Microsoft/testfx/pull/609
But I can not see any update in nuget version from last 23 days for version 2.0.0-beta4 and there is no version after that right now. https://www.nuget.org/packages/MSTest.TestFramework/
Intermediate fix is to use latest bits from here till there is new update with this fix:
https://dotnet.myget.org/F/mstestv2/api/v3/index.json
In particular, you should update your adapter and framework nuget package to these versions:
https://dotnet.myget.org/feed/mstestv2/package/nuget/MSTest.TestAdapter/2.0.0-build-20190430-01
https://dotnet.myget.org/feed/mstestv2/package/nuget/MSTest.TestFramework/2.0.0-build-20190430-01
Update 09/2019: the v2 of the MS Test Framework was officially released with the method in question included.

ServiceStack Service which has a Stream in its request breaks metadata page

When I create a simple ServiceStack service with a Stream in the request, I find that I am unable to access the metadata page for the service method.
The service itself appears to work (I can send a stream to http://localhost:12345/uploadStream using PostMan and I can deserialize the stream in the service method OK with a bit of extra code.)
I am using .NET Core and Servicestack...
Complete repo:
using Funq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceStack;
using ServiceStack.Web;
using System;
using System.IO;
using System.Threading.Tasks;
namespace ServiceStackCoreTest
{
class Program
{
static void Main(string[] args)
{
IWebHost host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls("http://*:12345/test/")
.Build();
host.Run();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services){ }
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.ApplicationServices.GetService<ILoggerFactory>();
app.UseServiceStack((AppHostBase)Activator.CreateInstance<AppHost>());
app.Run((RequestDelegate)(context => (Task)Task.FromResult<int>(0)));
}
}
public class AppHost : AppHostBase
{
public AppHost() : base("Test Service", typeof(Program).GetAssembly()){ }
public override void Configure(Container container){ }
}
public class MyService : Service
{
public TestResponse Any(TestRequest request)
{
return new TestResponse();
}
}
[Route("/uploadStream", "POST", Summary = "Upload stream")]
public class TestRequest : IReturn<TestResponse>, IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public class TestResponse{ }
}
My complete csproj (I am using Windows 10 / VS2017)...
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.1.1" />
<PackageReference Include="ServiceStack.Core" Version="1.0.40" />
<PackageReference Include="ServiceStack.Kestrel" Version="1.0.40" />
</ItemGroup>
</Project>
When I browse to the metadata page, I can see the list of operations, but when I click on 'XML', 'JSON' or 'JSV' next to the 'TestRequest' method, I get an error ERR_INCOMPLETE_CHUNKED_ENCODING in chrome (Edge reports nothing), and in my output window, I see Exception thrown: 'System.MemberAccessException' in System.Private.CoreLib.ni.dll. Oddly enough, clicking on 'CSV' gives me a metadata page.
Am I creating the service method incorrectly in my ServiceStack project?
The .NET Core package had an issue where wasn't able to create an instance of an abstract class (Stream) which should now be resolved from this commit.
This change is available from v1.0.41 *.Core packages that are now available on NuGet.

Categories

Resources