I want to integration test an ASP.NET Core MVC WebSite. I started by adding an empty MVC WebApplication project:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
</ItemGroup>
</Project>
It runs and shows the ASP.NET Core MVC sample page.
Then I added an XUnit-Project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WebApplication1\WebApplication1.csproj" />
</ItemGroup>
</Project>
Where I added the nuget package Microsoft.AspNetCore.TestHost.
The following test fails with a CompilationFailedException:
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using WebApplication1;
using Xunit;
public class UnitTest1
{
[Fact]
public async void Test1()
{
var builder = new WebHostBuilder()
.UseContentRoot(#"C:\path\to\WebApplication1")
.UseStartup<Startup>();
var server = new TestServer(builder);
var client = server.CreateClient();
var _ = await client.GetAsync("/");
}
}
Exception details:
Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException : One or more compilation failures occurred:
oxhek45x.0i3(4,62): error CS0012: The type 'Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
oxhek45x.0i3(4,81): error CS0518: Predefined type 'System.String' is not defined or imported
oxhek45x.0i3(4,110): error CS0518: Predefined type 'System.Type' is not defined or imported
oxhek45x.0i3(4,11): error CS0518: Predefined type 'System.Void' is not defined or imported
#542 and #2981 describe similar problems.
I tried adding this to the test project, but it didn't help:
<ItemGroup>
<Reference Include="netstandard" />
</ItemGroup>
And I tried replacing the MetadataReferenceFeature as described in #2981.
Found a "solution" that works for me:
Set the Content Root to the folder of the web project
Copy the *.deps.json file from the output folder of the web project to the output folder of the test project
This process will be made easier in ASP.NET Core 2.1. Found the solution here. More details about the new feature in 2.1 can be found here.
This article explains how to automize step 2:
Just add this in to your test csproj-file:
<Copy SourceFiles="%(DepsFilePaths.FullPath)" DestinationFolder="$(OutputPath)" Condition="Exists('%(DepsFilePaths.FullPath)')" />
Related
After spending way too much time, I still can't make Roslyn to load simple C# project.
Project source:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.11.0" />
</ItemGroup>
</Project>
Code that is trying to load:
using System;
using Microsoft.CodeAnalysis.MSBuild;
namespace Metrics5
{
class Program
{
static void Main(string[] args)
{
using var workspace = MSBuildWorkspace.Create();
workspace.LoadMetadataForReferencedProjects = true;
var currentProject = workspace.OpenProjectAsync(#"C:\work\Metrics5\Metrics5.csproj").Result;
var diagnostics = workspace.Diagnostics;
foreach(var diagnostic in diagnostics)
{
Console.WriteLine(diagnostic.Message);
}
}
}
}
It says:
Msbuild failed when processing the file 'C:\work\Metrics5\Metrics5.csproj' with message: The SDK 'Microsoft.NET.Sdk' specified could not be found. C:\work\Metrics5\Metrics5.csproj
After I add MSBuildSDKsPath as environment value MSBuildSDKsPath=C:\Program Files\dotnet\sdk\5.0.301\Sdks it seems to pass that step and stuck in another:
Msbuild failed when processing the file 'C:\work\Metrics5\Metrics5.csproj' with message: The imported project "C:\work\Metrics5\bin\Debug\net5.0\Current\Microsoft.Common.props" was not found. Confirm that the expression in the Import de
claration "C:\work\Metrics5\bin\Debug\net5.0\Current\Microsoft.Common.props" is correct, and that the file exists on disk. C:\Program Files\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props
And from here I'm not sure how to proceed, am I missing some nuget package?
Do I need to install additionally something?
Add reference to Microsoft.Build.Locator
I used the next packages:
<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.11.0" />
</ItemGroup>
Then register the instance of MSBuild using MSBuildLocator:
//add this line before using MSBuildWorkspace
MSBuildLocator.RegisterDefaults(); //select the recent SDK
using var workspace = MSBuildWorkspace.Create();
You Can control the version of MsBuild:
var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances();
//select NET5, or whatever by modifying Version.Major
var instance = visualStudioInstances.FirstOrDefault(x => x.Version.Major.ToString() == "5");
MSBuildLocator.RegisterInstance(instance);
I would like to use NUnit.Engine.ITestEventListener within my test solution. Specifically I would be looking for end of the run <test-run...>.
I implemented the interface ITestEventListener within C# code within my test csproj. I set a break point within the interface. Within Visual Studio, I began debugging tests; never hit the break point. I then wondered if this is a NUnit Engine thing and MSTest knows nothing of it. Am I correct that MSTest will never hit my breakpoint with my class that implements ITestEventListener?
Alright lets try something else like writing out to the console log by using nunit3-console.exe to run the tests. My output within the interface never wrote a thing - everything else wrote out properly. So, what am I doing incorrectly?
using System;
using NUnit.Engine;
using NUnit.Engine.Extensibility;
namespace Learning.NUnitInterface
{
[Extension]
public class MyTestListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine("Hello there, here is your data: ");
Console.WriteLine(report);
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit.Console" Version="3.12.0" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.12.0" />
<PackageReference Include="NUnit.Engine" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
</ItemGroup>
</Project>
From NUnit Documentation you need to use .addins file to install an extension:
.addins files are used to locate engine extensions.
And Console.WriteLine would probably not work, as it looks to be redirected, for a toy example a logging to a file could be used.
Thanks to #Charlie answer, I managed to make an example of NUnit engine extension for a .net core, as a separate dll, with a project as below:
MyNunitAddon\MyNunitAddon.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit.Engine" Version="3.12.0" />
</ItemGroup>
<ItemGroup>
<None Update="MyNunitAddon.addins">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
MyNunitAddon\MyNunitAddon.addins
MyNunitAddon.dll
MyNunitAddon\MyTestListener.cs
using System.IO;
using NUnit.Engine;
using NUnit.Engine.Extensibility;
namespace Learning.NUnitInterface
{
[Extension]
public class MyTestListener : ITestEventListener
{
private static void WriteToDummyLog(string text)
{
File.AppendAllLines("MyTestListener.log", new []{text});
}
public void OnTestEvent(string report)
{
WriteToDummyLog($"Hello there, here is your data: ");
WriteToDummyLog(report);
}
}
}
Then a test project referenced to this extension as a project reference:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyNunitAddon\MyNunitAddon.csproj" />
</ItemGroup>
</Project>
After running tests in this project, either via dotnet test command line or via Visual Studio 2019, I got MyTestListener.log file populated.
The NUnit engine is used by the console runner - and other runners - to execute tests. It doesn't refer to the framework at all and the framework doesn't refer to the engine. In other words, they are completely separate programs.
Consequently, when you extend the engine, you don't put the extension in your test assembly. You create a separate assembly and build it. Normally, the extension refers to nunit.engine.api and no other part of nunit.
After you have built your extension, you need to make it available to the engine. The details of how you do this depend on how you have installed the runner and engine in the first place, that is, whether from the msi package, a nuget package, etc.
Rather than list all the alternative approaches here, I'll leave it at that for now and modify this answer if you post info about how you have installed the console runner.
You can find all the details of how to develop an extension in the NUnit documentation. See https://docs.nunit.org/articles/nunit-engine/extensions/Index.html
I got a pretty simple dot-net-core Project. This includes a little MockServerLibrary based on kestrel, that returns some simple REST-replies in unittests.
The complete setup works fine on dotnetCore2.2. Switching to dotnetCore3.0 produces an error in the startup of the Server:
Output stream: Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Hosting.Abstractions, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Das System kann die angegebene Datei nicht finden.
File name: 'Microsoft.Extensions.Hosting.Abstractions, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
at ServerMock.RestMockStarter.RunServer(String[] args)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
but only, if this is done by the [OneTimeSetup] of the unit-test project. When I start the MockServer's main-Method stand alone, the server starts fine.
My Assumption is, that the Server-Start fails, because the ServerMock is a
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8</LangVersion>
</PropertyGroup>
(...)
but the unitTestProject is
<Project Sdk="Microsoft.NET.Sdk">
(...)
<ItemGroup>
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>
(...)
This seems not to a problem in 2.2, because we needed a explicit reference to the packages in the ServerMock
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="2.2.0" />
</ItemGroup>
As far as I understand, these refereces aren't needed anymore (far more: the need to be removed with 3.0), but it seems that they can't be loaded automatically, when started from my unit tests.
Maybe the error is already, that the ServerMock is directy referenced by the unitTest-Project:
<ItemGroup>
<ProjectReference Include="..\ServerMock\ServerMock.csproj" />
and the ServerStart is pretty hard-wired in the [OneTimeSetup]:
await RestMockStarter.RunServer(null);
I already tried to change the type of the unitTest-Project to Microsoft.NET.Sdk.Web, but then it's not longer possile to start/see any unitTests (at least with Rider, so I think this is not the way I should try to fix the problem)
I was able to solve the problem:
(1) Changed the ServerMock-project's csproj-file to
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8</LangVersion>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
From that point I assume it became a "usual" dot-net-core project, and with <FrameworkReference Include="Microsoft.AspNetCore.App" /> the references to the web-extensions are again explicit.
(2) Added
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
to the unit-test's csproj too.
(3) On that point it became al litte frustrating, because the error still occured, but deleting the bin/obj-folder then suddenly helped.
I'm using dotnet standard 2.0 (Visual Studio 2017) for gRPC. This is how my whole project looks like:
Messages.proto
syntax = "proto3";
package Messages;
message IdRequest{
int32 id = 1;
}
message NameResponse{
string name=1;
}
Name.proto
syntax = "proto3";
package Services;
import public "proto/messages.proto";
service NameService{
rpc GetNameById(Messages.IdRequest) returns (Messages.NameResponse);
}
Common.proj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="proto\messages.proto" />
<None Remove="proto\name.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
<PackageReference Include="Grpc" Version="2.24.0" />
<PackageReference Include="Grpc.Core" Version="2.24.0" />
<PackageReference Include="Grpc.Tools" Version="2.24.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Protobuf Include="proto\messages.proto" />
<Protobuf Include="proto\name.proto" />
</ItemGroup>
</Project>
The project builds successfully however the final Common.dll has no Messages namespace and I cannot really reference IdRequest or NameResponse.
So where am I making the mistake that hides Messages namespace?
In your project file into the Protobuf-tag you need to add the GrpcServices attribute or else no code is created:
<ItemGroup>
<Protobuf Include="proto\messages.proto" GrpcServices="Server" />
<Protobuf Include="proto\name.proto" GrpcServices="Server" />
</ItemGroup>
I know this is so old, but in case it is helpful for someone else. The documentation for gRPC has greatly improved since the asking of this question.
Looking at the tags associated, but also from the discussions and screenshots from here, I'm going to make the assumption that the project was working with csharp, as this makes a difference. I believe the namespaces are not generated correctly because the option "csharp_namespace" is missing.
The service will also have its namespace changed because of this amendment.
Message.proto:
syntax = "proto3";
package Messages;
option csharp_namespace = "Messages";
message IdRequest{
int32 id = 1;
}
message NameResponse{
string name=1;
}
Name.proto:
syntax = "proto3";
package Services;
option csharp_namespace = "Messages";
import "proto/Messages.proto";
service NameService{
rpc GetNameById(Messages.IdRequest) returns (Messages.NameResponse);
}
I am trying to call api using Flurl and here is my request which only fails on my testserver but works on live server and localhost as well
PickUp responseAsPickUpPointServiceResponse = null;
try
{
responseAsPickUpPointServiceResponse =
await new Flurl.Url(_baseUrl + "/rest//v1/servicepoint/findByPostalCode.json")
.SetQueryParam("apikey", APIKEY_WEB1)
.SetQueryParam("countryCode", countrycode)
.SetQueryParam("postalCode", zipcode)
.WithHeader("Accept", "application/json;charset=UTF-8")
.GetJsonAsync<PickUp>();
}
BUt it fails with error
Method not found: 'System.Threading.Tasks.Task`1 Flurl.Http.GeneratedExtensions.GetJsonAsync(Flurl.Http.IFlurlRequest, System.Threading.CancellationToken, System.Net.Http.HttpCompletionOption)
Has anyone idea how to fix this?
Same here, I got the same error Method not found [...] GetJsonAsync when running my integration tests although it was working well with unit tests.
In my case, there were two projects where Flurl.Http versions mismatched :
main.csproj
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Flurl" Version="3.0.0" />
<PackageReference Include="Flurl.Http" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\other\imported.csproj" />
</ItemGroup>
</Project>
imported.csproj
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Flurl" Version="2.8.2" />
<PackageReference Include="Flurl.Http" Version="2.4.2" />
</ItemGroup>
</Project>
The error was fixed by bumping Flurl version to 3.0.1 everywhere :
In both files :
<PackageReference Include="Flurl" Version="3.0.1" />
<PackageReference Include="Flurl.Http" Version="3.0.1" />