Tests do not work - c#

i try add a new tests in my class test, but the new method just don't work. i use xUnit and MOQ.
[Theory]
[Trait("Category", "Selecao")]
public void teste()
{
Assert.Empty("");
}

Replace [Theory] with [Fact]
A [Theory] must have testdata, like this:
[Theory]
[InlineData(3)]
[InlineData(5)]
[InlineData(6)]
public void MyFirstTheory(int value)
{
Assert.True(IsOdd(value));
}
For [Fact], this is not needed, example:
[Fact]
public void MyTest()
{
Assert.Empty("");
}
More info at: http://xunit.github.io/docs/getting-started-desktop#write-first-theory

Related

Does AutoFixture support `DateOnly` for .NET6?

I'm getting exception on constructing DateOnly variables/fields with AutoFixture.
(constructing of TimeOnly works fine)
AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from System.DateOnly because creation unexpectedly failed with exception. Please refer to the inner exception to investigate the root cause of the failure.
AutoFixture, AutoFixture.NUnit3 nugets version: 4.17.0
using AutoFixture;
using AutoFixture.NUnit3;
using NUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class AutoFixtureCreateTests
{
private readonly Fixture fixture = new();
[SetUp]
public void Setup()
{
var date = fixture.Create<DateOnly>(); //fails
var time = fixture.Create<TimeOnly>(); //works fine
}
[Test, AutoData]
public void CreateString(string str) { } //works fine
[Test, AutoData]
public void CreateDateOnly(DateOnly date) { } //fails
[Test, AutoData]
public void CreateTimeOnly(TimeOnly time) { } //works fine
}
}
The answer: at the moment does not.
There is a pull request: https://github.com/AutoFixture/AutoFixture/pull/1305
(however it's in open state almost for a year, without any milestones)
But there is a workaround.
My temporary solution is to create AutoFixture customization (CustomFixture.cs) file and include it to the project:
using AutoFixture;
using AutoFixture.NUnit3;
namespace UnitTests
{
public class CustomFixture
{
public static Fixture Create()
{
var fixture = new Fixture();
fixture.Customize<DateOnly>(composer => composer.FromFactory<DateTime>(DateOnly.FromDateTime));
return fixture;
}
}
public class CustomAutoDataAttribute : AutoDataAttribute
{
public CustomAutoDataAttribute()
: base(()=>CustomFixture.Create())
{}
}
}
After it include customization in the test code:
using AutoFixture;
using AutoFixture.NUnit3;
using NUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class AutoFixtureCreateTests
{
private readonly Fixture fixture =
CustomFixture.Create(); //custom factory
[SetUp]
public void Setup()
{
var date = fixture.Create<DateOnly>(); //now works
var time = fixture.Create<TimeOnly>();
}
[Test, AutoData]
public void CreateString(string str) { }
[Test, CustomAutoData] //custom attribute
public void CreateDateOnly(DateOnly date) { } //now works
[Test, AutoData]
public void CreateTimeOnly(TimeOnly time) { }
}
}

C# UnitTest void static method

I'm trying to make an unit test for a logger in an application.
For example I need to test the method Logger.info("some message"), but this method is static and return void.
Searching on Google I understand that I have to use Moq but am unable to implement that on the UnitTest class.
The Logger constructor does not have an argument and in x.Debug I have an error that says that I can't access
from instance reference.
Is there a way to implement UnitTest without editing the production code?
[TestClass()]
public class LoggerTests
{
[TestMethod()]
public void DebugTest()
{
var mock = new Mock<Logger>();
mock.Setup(x => x.Debug(It.IsAny<string>());
new Logger(mock.Object).AddLog("testing");
mock.VerifyAll;
}
}
Program.cs
private static void ConfigureLogger()
{
Logger.AddLog(new NLogAppender());
Logger.Level = TraceLevel.Verbose;
Logger.Info("Configured Logger");
}
Logger.cs
public class Logger
{
public static readonly List<IAppender> loggings = new List<IAppender>();
public static void AddLog(IAppender appender)
{
loggings.Add(appender);
}
public static TraceLevel Level { get; set; }
static Logger()
{
Level = TraceLevel.Verbose;
}
public static void Info(string message)
{
LogMessage(message);
}
}
NlogAppender.cs
public class NLogAppender : IAppender
{
public NLog.Logger logger;
public NLogAppender()
{
logger = LogManager.GetLogger(nameof(NLogAppender));
}
public void AddLog(string str)
{
}
}
IAppender.cs
public interface IAppender
{
void AddLog(string str);
}
You can't mock a static class, and you shouldn't mock the class/system under test.
Add a mock appender to the logger:
// Arrange
var logString = "test-info"
var appenderMock = new Mock<IAppender>();
appenderMock.Setup(a => a.AddLog(logString));
Logger.AddLog(appenderMock.Object);
// Act
Logger.Info(logString);
// Assert
// TODO: exactly once
appenderMock.VerifyAll();
Note this static class may persist data between tests causing unexpected results, consult your test framework for configuring this.
Apart from that, you usually don't want to roll your own logging infrastructure, there's lots of things you can do wrong and why reinvent the wheel? Plenty of ILogger(<T>) implementations around.

Test method with param Action<T> with Nunit and Moq c#

I'm using c#, Nunit and Moq and I want to test a method like the Remove() method, that call another method with an Action<> parameter.
public class Db
{
private readonly IMessageWrapper _messageWrapper;
private readonly IProvider _provider;
public Db(IMessageWrapper messageWrapper, IProvider provider)
{
_messageWrapper = messageWrapper;
_provider = provider;
}
public void Remove()
{
Execute(transaction =>
{
// Do something
// method to verify with unit test
_messageWrapper.SendData();
});
}
private void Execute(Action<SqlTransaction> action)
{
_provider.ExecuteAction(action);
}
}
I'd like to do something like:
public class DbTest
{
[Test]
public void Remove_Should_SendData()
{
//... create IMessageWrapper mock and IProvider mock...
var db = new Db(messageWrapperMock.Object, provider.Object);
provider.Setup(p => p.ExecuteAction(It.IsAny<Action<SqlTransaction>>));
db.Remove();
messageWrapperMock.Verify(m => m.SendData(), Times.Once());
}
}
But it doesn't work. The unit test doesn't reach the _messageWrapper.SendData();
Thanks for the help
When you setup without any code - that method does nothing, but you need it to call your action.
Try this:
provider.Setup(p => p.ExecuteAction(It.IsAny<Action<SqlTransaction>>()))
.Callback<Action<SqlTransaction>>(c => c(null));

Nsubstitute executing Action as parameter on a mocked interface

Is there anyway I can execute an action as a parameter from a mocked out service?
I have an interface that is used in the method I am unit testing:
interface IMyTracker
{
void TrackerMethod(string name, Action action);
}
This is the method I want to unit test:
private void Method1(IMyTracker myTracker)
{
myTracker.TrackerMethod("Method1",() =>
{
// This is stuff I want to execute!
}
}
Here is my unit test
[Test]
public void TestMethod1()
{
var trackerSub = Substitute.For<IMyTracker>();
trackerSub.TrackerMethod(Arg.Any<string>(), Arg.Invoke<Action>()); //How do I execute the logic inside the lambda expression action? Is it at all possible? Or once it's mocked, is that logic lost?
GetClassInstance().Method1(trackerSub);
}
Any help here would be great.
i created example code which show you how it works.
So at the start we get you interface:
public interface ITracker
{
void TrackerMethod(string name, Action action);
}
Next we got the sample class which use this interface and do any action in the tracker, look here:
public class AnyClass
{
private readonly ILogger _anyLogger;
public AnyClass(ILogger anyLogger)
{
this._anyLogger = anyLogger;
}
public void AnyMethod(ITracker tracker)
{
tracker.TrackerMethod("mymethod", () =>
{
_anyLogger.LogError("i was here");
});
}
}
and the unit test for this scenario can look like:
[Fact]
public void TestMethod1()
{
var logger = Substitute.For<ILogger>();
var tracker = Substitute.For<ITracker>();
tracker.TrackerMethod(Arg.Any<string>(), Arg.Invoke());
AnyClass anyClass = new AnyClass(logger);
anyClass.AnyMethod(tracker);
logger.Received().LogError("i was here");
}

AssemblyInitialize method doesnt run before tests

I am using MsTest V2 framewrok for my tests.
I have Test automation framework (TAF) project and project with tests.
Tests project inherited from TAF and contains only tests.
In TAF i have a class which contains method which should run before all tests but it doesnt work at all.
By the way BeforeTest method works fine.
public class TestBase
{
[AssemblyInitialize]
public static void BeforeClass(TestContext tc)
{
Console.WriteLine("Before all tests");
}
[TestInitialize]
public void BeforeTest()
{
Console.WriteLine("Before each test");
}
}
[TestClass]
public class FirstTest : TestBase
{
[TestMethod]
public void FailedTest()
{
Assert.IsTrue(false,"ASDASDASD");
}
}
If I put "AssemblyInitialize" method to tests projects then it work.
What am I doing wrong?
Just put [TestClass] onto your TestBase:
[TestClass]
public class TestBase
{
[AssemblyInitialize]
public static void BeforeClass(TestContext tc)
{
Console.WriteLine("Before all tests");
}
[TestInitialize]
public void BeforeTest()
{
Console.WriteLine("Before each test");
}
}

Categories