Why empty collection assertion does not work in MSTest? - tdd

I have an assertion like the following
Assert.AreEqual(1.Primes(), new List());
Where Primes returns IList and the code for primes is
public static class PrimesKata
{
public static IList Primes(this int n)
{
return new List();
}
}
as you can guess I am trying out the prime number kata, when using MSTest for unit testing this test fails but the same code works just fine in NUnit. Is there something extra I need to do in MSTest for this test to pass?

NUnit's Assert supports equality of collections.
MSUnit doesn't. You can use CollectionAssert in MSTest instead.
In .NET (unlike Java, for instance) two lists are not equal just because they have the same contents.

Related

Multiplatform runBlocking coroutine tests fail if last assertion doesn't have a Unit return type

I'm testing my coroutine functions in my Kotlin Multiplatform project. I've mocked out the implementation behind them, so no actual await occurs during tests.
Consider the following test, curated from the test README:
#Test fun testAsyncFunction() = runBlocking {
val result: List<myClass> = myService.someSuspendFunction()
assertEquals(result.first()?.name, "name")
assertNotNull(result.first()?.someRequiredValue)
}
The second assertion has a return type of T, which causes its result to be returned to the runBlocking function, throwing the following error:
Invalid test class 'com.example.shared.core.service.ExampleTests':
1. Method testAsyncFunction() should be void
I've found 2 solutions to this, either I can swap the two assertions around (assertEquals has a Unit return type, thus no issues), or write val ignored = assertNotNull(result.first()?.someRequiredValue). However neither of these two solutions are ideal, as I'll either have extraneous code that my IDE is warning me to remove, or my assertions are out of order.
What is the best solution to this issue?
The problem is that the method is inferring the return type from runBlocking, which returns value from the inner suspending function.
You can force it to generate a void return type by specifying the return type : Unit explicitly rather than rely on the inferred value.

VS Code Coverage won't recognize only possible Expression Lambda Path

I have following Extension Method which is just a negation of Linq.Any()
These two UnitTests do test it completely
[TestMethod]
public void EnumerableExtensions_None_WithMatch()
{
Assert.IsTrue(_animals.None(t => t.Name == "Pony"));
}
[TestMethod]
public void EnumerableExtensions_None()
{
var emtpyList = new List<Animal>(); { };
Assert.IsTrue(emtpyList.None());
}
As you can see in the picture, when I run a Code Coverage Analysis, the delegate body is not covered (white selection), because of the deferred execution.
This question comes close to the problem:
Code Coverage on Lambda Expressions
But does not quite solve it: Since the List must stay empty, it's impossible to actually step into that piece of code.
I am tempted to mark the segment with [ExcludeFromCodeCoverage] ...
How would you write the UnitTest?
You need to test that None() returns false when given a non-empty list of Animal. As it is, you never execute your default lambda expression.
You might even find a bug...
This is the correct way to write the Test. Even found a bug!
public void EnumerableExtensions_None()
{
// _animals HAS entries
Assert.IsFalse(_animals.None());
}
Code Coverage 100%!

Postconditions and TDD

One colleague in my team says that some methods should have both preconditions & postconditions. But the point is about code coverage, those conditions were not being called (not tested) until an invalid implementation implemented (just used in unit test). Lets take below example.
public interface ICalculator
{
int Calculate(int x, int y);
}
public int GetSummary(int x, int y)
{
// preconditions
var result = calculator.Calculate(x, y);
// postconditions
if (result < 0)
{
**throw new Exception("...");**
}
return result;
}
Two options for us:
1/ Remove test implementations + postconditions
2/ Keep both test implementations + postconditions
Can you give some advice please?
Keep pre- and post-conditions.
You'll need at least four tests here: combinations of (pre, post) x (pass, fail). Your failing post-condition test will pass if the expected exception is thrown.
This is easy to do in JUnit with its #Test(expected = Exception.class) annotation.
Be careful with colleagues that make blanket statements like "X must always be true." Dogma in all its forms should be avoided. Understand the reasons for doing things and do them when they make sense.
These conditions should be seen from design view. They ensure the calculator should be working fine, returning result in a range of expected values.
You should see the MS code contracts project to take a document there.

How can I intercept the result of an IQueryProvider query (other than single result)

I'm using Entity Framework and I have a custum IQueryProvider. I use the Execute method so that I can modify the result (a POCO) of a query after is has been executed. I want to do the same for collections. The problem is that the Execute method is only called for single result.
As described on MSDN :
The Execute method executes queries that return a single value
(instead of an enumerable sequence of values). Expression trees that
represent queries that return enumerable results are executed when
their associated IQueryable object is enumerated.
Is there another way to accomplish what I want that I missed?
I know I could write a specific method inside a repository or whatever but I want to apply this to all possible queries.
This is true that the actual signature is:
public object Execute(Expression expression)
public TResult Execute<TResult>(Expression expression)
However, that does not mean that the TResult will always be a single element! It is the type expected to be returned from the expression.
Also, note that there are no constraints over the TResult, not even 'class' or 'new()'.
The TResult is a MyObject when your expression is of singular result, like .FirstOrDefault(). However, the TResult can also be a double when you .Avg() over the query, and also it can be IEnumerable<MyObject> when your query is plain .Select.Where.
Proof(*) - I've just set a breakpoint inside my Execute() implementation, and I've inspected it with Watches:
typeof(TResult).FullName "System.Collections.Generic.IEnumerable`1[[xxxxxx,xxxxx]]"
expression.Type.FullName "System.Linq.IQueryable`1[[xxxxxx,xxxxx]]"
I admit that three overloads, one object, one TResult and one IEnumerable<TResult> would probably be more readable. I think they did not place three of them as extensibility point for future interfaces. I can imagine that in future they came up with something more robust than IEnumerable, and then they'd need to add another overload and so on. With simple this interface can process any type.
Oh, see, we now also have IQueryable in addition to IEnumerable, so it would need at least four overloads:)
The Proof is marked with (*) because I have had a small bug/feature in my IQueryProvider's code that has is obscuring the real behavior of LINQ.
LINQ indeed calls the generic Execute only for singular cases. This is a shortcut, an optimization.
For all other cases, it ... doesn't call Execute() it at all
For those all other cases, the LINQ calls .GetEnumerator on your custom IQueryable<> implementation, that what happens is dictated by .. simply what you wrote there. I mean, assuming that you actually provided custom implementations of IQueryable. That would be strange if you did not - that's just about 15 lines in total, nothing compared to the length of custom provider.
In the project where I got the "proof" from, my implementation looks like:
public System.Collections.IEnumerator GetEnumerator()
{
return Provider.Execute<IEnumerable>( this.Expression ).GetEnumerator();
}
public IEnumerator<TOut> GetEnumerator()
{
return Provider.Execute<IEnumerable<TOut>>( this.Expression ).GetEnumerator();
}
of course, one of them would be explicit due to name collision. Please note that to fetch the enumerator, I actually call the Execute with explicitely stated TResult. This is why in my "proof" those types occurred.
I think that you see the "TResult = Single Element" case, because you wrote i.e. something like this:
public IEnumerator<TOut> GetEnumerator()
{
return Provider.Execute<TOut>( this.Expression ).GetEnumerator();
}
Which really renders your Execute implementation without choice, and must return single element. IMHO, this is just a bug in your code. You could have done it like in my example above, or you could simply use the untyped Execute:
public System.Collections.IEnumerator GetEnumerator()
{
return ((IEnumerable)Provider.Execute( this.Expression )).GetEnumerator();
}
public IEnumerator<TOut> GetEnumerator()
{
return ((IEnumerable<TOut>)Provider.Execute( this.Expression )).GetEnumerator();
}
Of course, your implementation of Execute must make sure to return proper IEnumerables for such queries!
Expression trees that represent queries that return enumerable results are executed when their associated IQueryable object is enumerated.
I recommend enumerating your query:
foreach(T t in query)
{
CustomModification(t);
}
Your IQueryProvider must implement CreateQuery<T>. You get to choose the implemenation of the resulting IQueryable. If you want that IQueryable to do something to each row when enumerated, you get to write that implementation.
The final answer is that it's not possible.

Testing A Function That Always Returns True

How would one write a test for the following function?
bool IsAnInterger(int ignore)
{
return true
}
I don't have enough time to iterate over every integer (for the actual code the parameter isn't even an integer).
This is used as part of the Specification Pattern, so that I can implement a Null Object.
... testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.
-- Edsger W. Dijkstra
I'd say that it's pointless to try to exhaustively black box test this function. It is better to test it in a context similar to where it will be used.
In TDD, you write the test first and that test should specify a specific behavior. So the question should always be: What do I expect to happen? - and then write the test to verify that behavior - finally write the solution to make the test pass.
edit: Understanding the question
Do you mean that this function is the behavior for a non-existent specification, e.g. a Null specification? You can of course test this null specification that it behaves in a certain way. At a guess though, this will pretty much be hard-coded one-line return values (if anything). The tests for this null object would then basically only document what the null specification should do. It won't add any other extra business value to the system.
Since you cannot reasonably test every case, you can use Mathematical Induction as a basis for your tests. You can't do this algebraically, but you can pick an arbitrary value for n.
#include <limits>
#include <cassert>
bool IsAnInteger(int)
{
return true;
}
int main()
{
assert(IsAnInteger(std::numeric_limits<int>::min())); // First
assert(IsAnInteger(0)); // n
assert(IsAnInteger(1)); // n+1
}
Edit
Hold on!
for the actual code the parameter isn't even an integer
What is it then?
#include <cassert>
template <class T>
bool IsAnInteger(const T&)
{
return true;
}
int main()
{
assert(IsAnInteger(0)); // First
assert(IsAnInteger("I am not a number!")); // n
assert(IsAnInteger(42.0f)); // n+x
}
Your function has 100% test coverage and your unit tests accurately document how it behaves. In TDD you only need to write just enough code so that your unit tests pass. You're done with this and can move on.

Resources