Trying to create unit tests for my methods and can't seem to get the configuration right.
I go New Test -> Unit Test Wizard -> Pick my method -> fill in test method values but I always get Assert.Inconclusive failed. Verify the correctness of this test method.
Here is a sample method:
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
}
public int Mult(int a, int b)
{
return a * b;
}
}
}
and the test method:
[TestMethod()]
public void MultTest()
{
Program target = new Program(); // TODO: Initialize to an appropriate value
int a = 4; // TODO: Initialize to an appropriate value
int b = 5; // TODO: Initialize to an appropriate value
int expected = 20; // TODO: Initialize to an appropriate value
int actual;
actual = target.Mult(a, b);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
Seems straight forward enough, but am I missing something trivial?
The Assert.Inconclusive is mainly a marker to tell you that you need to right your own verification steps for the test method. In other words, for what you are doing it can be removed as you have added your own Assertion.
It could also be used, if there is some logic in your test that prevents the full running of your test. So, if, for example, you couldn't create the object you were trying to test for some reason.
sure you do :
Assert.Inconclusive("Verify the correctness of this test method.");
Your test says inconclusive therfore the result of the test is inconclusive.. You should use this syntax "Assert.Inconclusive" only to cover edge cases you are really aware of.
AFAIC, I never use it.
Related
Can I build my TestCaseData list in my SetUp? Because with this setup my test is just being skipped. Other regular tests are running just fine.
[TestFixture]
public class DirectReader
{
private XDocument document;
private DirectUblReader directReader;
private static UblReaderResult result;
private static List<TestCaseData> rootElementsTypesData = new List<TestCaseData>();
[SetUp]
public void Setup()
{
var fileStream = ResourceReader.GetScenario("RequiredElements_2_1.xml");
document = XDocument.Load(fileStream);
directReader = new DirectUblReader();
result = directReader.Read(document);
// Is this allowed?
rootElementsTypesData.Add(new TestCaseData(result.Invoice.Id, new IdentifierType()));
rootElementsTypesData.Add(new TestCaseData(result.Invoice.IssueDate, new IdentifierType()));
}
[Test, TestCaseSource(nameof(rootElementsTypesData))]
public void Expects_TypeOfObject_ToBeTheSameAs_InputValue(object inputValue, object expectedTypeObject)
{
Assert.That(inputValue, Is.TypeOf(expectedTypeObject.GetType()));
}
}
As stated by #IMil, the answer is No... that's not possible.
TestCaseSource is used by NUnit to build a list of the tests to be run. It associates a method with a particular set of arguments. NUnit then creates an internal representation of all your tests.
OTOH SetUp (and even OneTimeSetUp is used when those tests are being run. By that time, the number of tests and the actual arguments to each of them are fixed nothing can change them.
So, in order to do what you seem to want to do, your TestCaseSource has to stand on it's own, fully identifying the arguments to be used for the test. That's why NUnit gives you the capability of making the source a method or property, rather than just a simple list.
In your case, I suggest something like...
private static IEnumerable<TestCaseData> RootElementsTypesData()
{
var fileStream = ResourceReader.GetScenario("RequiredElements_2_1.xml");
document = XDocument.Load(fileStream);
directReader = new DirectUblReader();
result = directReader.Read(document);
yield return new TestCaseData(result.Invoice.Id, new IdentifierType()));
yield return new TestCaseData(result.Invoice.IssueDate, new IdentifierType()));
}
Obviously, this is only "forum code" and you'll have to work with it to get something that actually compiles and works for your case.
No, this is impossible.
Methods decorated with [SetUp] are run before each test case.
This means NUnit will first build list of test cases, then run Setup() before each of them.
Therefore, your Setup() never gets called, and list of test cases remains empty.
I'm using Moq for my Unit Tests and have got the following method:
[TestMethod]
public void GetTestRunById_ValidId_TestRunReturned()
{
var mockTestRunRepo = new Mock<IRepository<TestRun>>();
var testDb = new Mock<IUnitOfWork>();
testDb.SetupGet(m => m.TestRunsRepo).Returns(mockTestRunRepo.Object);
TestRun returnedRun = EntityHelper.getTestRunByID(testDb.Object, 1);
}
The method in question which is being tested is getTestRunByID(). I have confirmed that this method is called when debugging this unit test, but as expected getTestRunByID() doesn't return anything since the mock has no data inside it.
Would all that matter is the method gets hit and returns null? If not, how can I add data to my mockTestRunRepo when it's only present as a returned value from testDb?
For reference the method being tested is:
public static TestRun getTestRunByID(IUnitOfWork database, int testRun)
{
TestRun _testRun = database.TestRunsRepo.getByID(testRun);
return _testRun;
}
The purpose of the unit test is to ONLY test the small method getTestRunByID. For that, test if it was called exactly once with that integer parameters, 1.
mockTestRunRepo.Verify(m => m.getByID(1), Times.Once());
You must also set up the method getByID for mockTestRunRepo, to make it return a specific value, and test if the result value of the test run is equal to what you expected.
//instantiate something to be a TestRun object.
//Not sure if abstract base class or you can just use new TestRun()
mockTestRunRepo.Setup(m => m.getByID(1)).Returns(something);
Test if you get the same value
TestRun returnedRun = EntityHelper.getTestRunByID(testDb.Object, 1);
Assert.AreEqual(returnedRun, something);
This code might be prone to errors, as I do not have an environment to test it right now. But this is the general idea behind a unit test.
This way, you test if the method getById runs as expected, and returns the expected result.
You have your repository return data the same way that you setup everything else.
var mockTestRunRepo = new Mock<IRepository<TestRun>>();
// This step can be moved into the individual tests if you initialize
// mockTestRunRepo as a Class-level variable before each test to save code.
mockTestRunRepo.Setup(m => m.getById(1)).Returns(new TestRun());
Per #Sign's recommendation, if you know that you're calling it with 1, then use that instead of It.IsAny<int>() to keep things cleaner.
I'm writing a unit test for this one method which returns "void". I would like to have one case that the test passes when there is no exception thrown. How do I write that in C#?
Assert.IsTrue(????)
(My guess is this is how I should check, but what goes into "???")
I hope my question is clear enough.
Your unit test will fail anyway if an exception is thrown - you don't need to put in a special assert.
This is one of the few scenarios where you will see unit tests with no assertions at all - the test will implicitly fail if an exception is raised.
However, if you really did want to write an assertion for this - perhaps to be able to catch the exception and report "expected no exception but got this...", you can do this:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(the above is an example for NUnit, but the same holds true for MSTest)
In NUnit, you can use:
Assert.DoesNotThrow(<expression>);
to assert that your code does not throw an exception. Although the test would fail if an exception is thrown even if there was no Assert around it, the value of this approach is that you can then distinguish between unmet expectations and bugs in your tests, and you have the option of adding a custom message that will be displayed in your test output. A well-worded test output can help you locate errors in your code that have caused a test to fail.
I think it's valid to add tests to ensure that your code is not throwing exceptions; for example, imagine you are validating input and need to convert an incoming string to a long. There may be occasions when the string is null, and this is acceptable, so you want to ensure that the string conversion does not throw an exception. There will therefore be code to handle this occasion, and if you haven't written a test for it you will be missing coverage around an important piece of logic.
This helper class scratched my itch with MSTest. Maybe it can scratch yours also.
[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
// Arrange
var factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
// Assert
AssertEx.NoExceptionThrown<FormatException>(() =>
// Act
_service.ScheduleJob(scheduler)
);
}
public sealed class AssertEx
{
public static void NoExceptionThrown<T>(Action a) where T:Exception
{
try
{
a();
}
catch (T)
{
Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
}
}
}
Don't test that something doesn't happen. It's like assuring that code doesn't break. That's sort of implied, we all strive for non-breaking, bug-less code. You want to write tests for that? Why just one method? Don't you want all your methods being tested that they don't throw some exception? Following that road, you'll end up with one extra, dummy, assert-less test for every method in your code base. It brings no value.
Of course, if your requirement is to verify method does catch exceptions, you do test that (or reversing it a bit; test that it does not throw what it is supposed to catch).
However, the general approach/practices remain intact - you don't write tests for some artificial/vague requirements that are out of scope of tested code (and testing that "it works" or "doesn't throw" is usually an example of such - especially in scenario when method's responsibilities are well known).
To put it simple - focus on what your code has to do and test for that.
I like to see an Assert.Whatever at the end of each test, just for consistency... without one, can I really be sure there's not supposed to be one there?
For me, this is as simple as putting Assert.IsTrue(true);
I know I didn't accidentally put that code in there, and thus I should be confident enough at quick a skim through that this was as intended.
[TestMethod]
public void ProjectRejectsGappedVersioningByDefault() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
var sut = new ScriptProject(files);
});
}
[TestMethod]
public void ProjectAcceptsGappedVersionsExplicitly() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
var sut = new ScriptProject(files, true);
Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like
}
My friend Tim told me about ExpectedException. I really like this b/c it is more succinct, less code, and very explicit that you are testing for an exception.
[TestMethod()]
[ExpectedException(typeof(System.Exception))]
public void DivideTest()
{
int numerator = 4;
int denominator = 0;
int actual = numerator / denominator;
}
You can read way more about it here: ExpectedException Attribute Usage.
With Xunit you can use this:
var exception = Record.Exception(() =>
MethodUnderTest());
Assert.Null(exception);
or for async operations
var exception = await Record.ExceptionAsync(async () =>
await MethodUnderTestAsync());
Assert.Null(exception);
Another way which worked for me is to store it in a variable and check output.
var result = service.Run()
Assert.IsFalse(result.Errors.Any())
using Moq;
using Xunit;
[Fact]
public void UnitTest_DoesNotThrow_Exception()
{
var builder = new Mock<ISomething>().Object;
//Act
var exception = Record.Exception(() => builder.SomeMethod());
//Assert
Assert.Null(exception);
}
Sometimes I stub dependencies in test class setup and then want to restub some of them in concrete test. But Rhino mocks remembers only the first stub value and it is a bit inconvenient.
someStub.Stub(x => x.SomeMethod(1)).Return(100);
var value1 = someStub.SomeMethod(1);
someStub.Stub(x => x.SomeMethod(1)).Return(200);
var value2 = someStub.SomeMethod(1);
value 2 will be equal to 100.
Is it a designed behaviour? Are there any workarounds?
I ran into a need to do this myself. I worked around it by using the WhenCalled function where you pass in an action to be executed when the function is called. This will give you more flexibility on what you can return at different points.
More info/activity on this stackoverflow thread:
Rhino Mocks: Re-assign a new result for a method on a stub and here:
Changing previously stubbed calls with Rhino Mocks.
I know this is old but hope it helps someone else.
You can work around it with inheritance. If you have a base test class and some test subclasses that run the tests, you can make the return value a protected property of the base test class, and set the value in the subclasses at a point before base. Initialize is called.
So (using MSTEST) you could have:
in your base class:
protected int ReturnVal{get; set;}
public void Init()
{
someStub = MockRepository.GenerateMock<ISomeStub>();
someStub.Stub(x => x.SomeMethod(1)).Return(ReturnVal);
}
in your subclass:
[TestInitialize]
public override Init()
{
ReturnVal = 200;
base.Init();
}
Yes, this is the designed behaviour.
The workaround I use most of the time is to create a helper method that will set up the stub for you, i.e.:
private X MockX()
{
return MockX(100);
}
private X MockX(int returnValue)
{
var x = MockRepository.GenerateStub<X>();
someStub.Stub(x => x.SomeMethod(1)).Return(returnValue);
return x;
}
and then in your test instead of using a mock created in SetUp, you call the appropriate function. The added benefit is that it is clear that your test is using some special values of the return values.
You can use mocks instead of stubs to record a scenario like that:
[Test]
public void Mytest()
{
var mocks = new MockRepository();
var someMock = mocks.DynamicMock<IFoo>();
someMock.SomeMethod(1);
LastCall.Return(100);
someMock.SomeMethod(1);
LastCall.Return(200);
mock.Replay(); // stop recording, go to replay mode
// actual test, normally you would test something which uses the mock here
int firstResult = someMock.SomeMethod(1);
int secondResult = someMock.SomeMethod(2);
// verify the expectations that were set up earlier
// (will fail if SomeMethod is not called as in the recorded scenario)
someMock.VerifyAll();
}
Mocks in Rhino Mocks are more complicated to set up than stubs. They also mix the definition of behavior with the creation of assertions (the record phase does both), and they rely on the ordering of method calls. This makes for brittle tests; stick to stubs unless you really need mocks.
So' I'm getting in Unit Testing. I created a really simple Function to test it.
public int MultiplyByFive(int x)
{
return x * 5;
}
The Test Method contains
[TestMethod()]
[DeploymentItem("UnitTestApp.exe")]
public void MultiplyByFiveTest()
{
Program_Accessor target = new Program_Accessor(); // TODO: Initialize to an appropriate value
int x = 5; // TODO: Initialize to an appropriate value
int expected = 25; // TODO: Initialize to an appropriate value
int actual;
actual = target.MultiplyByFive(x);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
But when I run the test it returns:
nunit http://dl.getdropbox.com/u/357576/nunit.jpg
"Assert.Inconclusive failed. Verify the correctness of this test method."
So what I'm doing wrong? thanks!
NUnit 2.5 added "inconclusive" as a result state in between success and failure. It's explained in the release notes here.
NUnit is doing exactly what you told it to do. The new inconclusive state does terminate the test. If you want a message displayed in the case of your Assert failing, Assert.AreEqual() has an overload that takes a message string. Use that, and remove Assert.Inconclusive().
Assert.AreEqual(expected, actual, "Verify the correctness of this test method.");
You need to remove the Assert.Inconclusive if you are certain your test is correct :)