Run the same test multiple times in xUnit with different implementations - c#

I want to be able to run the same test with multiple implementations of a dependency.
The normal way to do what I want is the following:
[Theory]
[InlineData(DoerType.Version1)]
[InlineData(DoerType.Version2)]
public void DoSomethingTest(DoerType type)
{
IDoSomething doer = Factory.Create(type);
string result = doer.DoSomething();
}
Here's an alternate impl where I've shifted the call to the Factory Method out into a custom attribute:
[Theory]
[DoerVersions(DoerType.Version1, DoerType.Version2)]
public void DoSomethingTest(IDoSomething doer)
{
string result = doer.DoSomething();
}
public class DoerVersionsAttribute : DataAttribute
{
private readonly DoerType[] doers;
public DoerVersionsAttribute(params DoerType[] doers)
{
this.doers = doers;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return doers.Select(d => new object[] { Factory.Create(d) });
}
}
But given the large amount of tests that I want to do with this, I'm looking for a clean and as-DRY-as-possible way to do it.
Is there a way to avoid the parameter altogether and, for example, set the implementation on the test class field (or its base class)?
public class Tests
{
private IDoSomething Doer;
[Theory]
[DoerVersions(DoerType.Version1,DoerType.Version2)]
public void DoSomethingTest()
{
string result = Doer.DoSomething();
}
}
Other ways of expressing the same intent could be acceptable too.
Edit: why do I want this?
I didn't include this in the original question to avoid discussions about my motives.
I want to be able to write tests with as little technical information as possible and then run them through different "interfaces". For example (this is still an approximation):
[Theory]
[Interfaces(Interface.WebChrome, Interface.WebFirefox, Interface.Android)]
public void ShouldBeAbleToSearchBook()
{
dsl.Users.Login("user1");
dsl.Searcher.Search("title:BDD");
dsl.Searcher.ShouldHaveResult("Some BDD book");
}
So, having parameters and factories on each test would add considerable noise to the information ratio.

Related

NUnit 3.x - TestCaseSource for descendant test classes

I currently have a set of unit tests which are consistent for a number of Rest API endpoints. Say the class is defined like so.
public abstract class GetAllRouteTests<TModel, TModule>
{
[Test]
public void HasModels_ReturnsPagedModel()
{
// Implemented test
}
}
With the implemented test fixture looking like:
[TestFixture(Category = "/api/route-to-test")]
public GetAllTheThings : GetAllRouteTests<TheThing, ModuleTheThings> { }
This enables me to run a number of common tests across all GET all/list routes. It also means that I have classes which are linked directly to the module being tested, and links between tests and code in Resharper / Visual Studio / CI "just work".
The challenge is that some routes require query parameters for testing other pathways through the route code;
e.g. /api/route-to-test?category=big.
As [TestCaseSource] requires a static field, property, or method there appears to be no nice way to override a list of query strings to pass. The closest thing I have come up with seems like a hack. Namely:
public abstract class GetAllRouteTests<TModel, TModule>
{
[TestCaseSource("StaticToDefineLater")]
public void HasModels_ReturnsPagedModel(dynamic args)
{
// Implemented test
}
}
[TestFixture(Category = "/api/route-to-test")]
public GetAllTheThings : GetAllRouteTests<TheThing, ModuleTheThings>
{
static IEnumerable<dynamic> StaticToDefineLater()
{
// yield return all the query things
}
}
This works because the static method is defined for the implemented test class, and is found by NUnit. Huge hack. Also problematic for someone else consuming the abstract class as they need to "know" to implement "StaticToDefineLater" as a static something.
I am looking for a better way of achieving this. It seems like non-static TestCaseSource sources were removed in NUnit 3.x, so that's out.
Thanks in advance.
NOTES:
GetAllRouteTests<> implements a number of tests, not just the one shown.
Iterating through all the routes in one test will "hide" what is covered, so would like to avoid that.
The way I solved a similar problem is by having a base source class that implements IEnumerable (another acceptable source for NUnit), consider if this design suits your usecase:
// in the parent fixture...
public abstract class TestCases : IEnumerable
{
protected abstract List<List<object>> Cases { get; }
public IEnumerator GetEnumerator()
{
return Cases.GetEnumerator();
}
}
// in tests
private class TestCasesForTestFoobar : TestCases
{
protected override List<List<object>> Cases => /* sets of args */
}
[TestCaseSource(typeof(TestCasesForTestFoobar))]
public void TestFoobar(List<object> args)
{
// implemented test
}

Moq tell if function was called [duplicate]

I have a base class:
public abstract class MyBaseClass
{
protected virtual void Method1()
{
}
}
and a derived class:
public class MyDerivedClass : MyBaseClass
{
public void Method2()
{
base.Method1();
}
}
I want to write a unit test for Method2 to verify that it calls Method1 on the base class. I'm using Moq as my mocking library. Is this possible?
I came across a related SO link:
Mocking a base class method call with Moq
in which the 2nd answer suggests it can be achieved by setting CallBase property to true on the mock object. However it's not clear how this would enable the call to the base class method (Method1 in the above example) to be verified.
Appreciate any assistance with this.
Unit tests should verify behavior, not implementation. There are several reasons for this:
The results are the goal, not how you get the results
Testing results allows you to improve the implementation without re-writing your tests
Implementations are harder to mock
You might be able to put in hooks or create mocks that verify that the base method was called, but do you really care how the answer was achieved, or do you care that the answer is right?
If the particular implementation you require has side effects that you can verify, then that is what you should be validating.
Mocking the base class from the perspective of the derived class is not possible. In your simple example, I would suggest one of the two options.
Option 1: In the event that MyDerivedClass really shouldn't care what MyBaseClass is up to, then use dependency injection! Yay abstraction!
public class MyClass
{
private readonly IUsedToBeBaseClass myDependency;
public MyClass(IUsedToBeBaseClass myDependency){
_myDependency = myDependency;
}
public void Method2()
{
_myDependency.Method1();
}
}
Elsewhere in test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var dependency = new Mock<IUsedToBeBaseClass>();
var unitUnderTest = new MyClass(dependency.Object);
var unitUnderTest.Method2();
dependency.Verify(x => x.Method1(), Times.Once);
}
}
Option 2: In the event that MyDerivedClass NEEDS to know what MyBaseClass is doing, then test that MyBaseClass is doing the right thing.
In alternative test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var unitUnderTest = new MyDerivedClass();
var unitUnderTest.Method2();
/* verify base class behavior #1 inside Method1() */
/* verify base class behavior #2 inside Method1() */
/* ... */
}
}
What you're describing is not a test of your code, but a test of the behavior of the language. That's fine, because it's a good way to ensure that the language behaves the way we think it does. I used to write lots of little console apps when I was learning. I wish I'd known about unit testing then because it's a better way to go about it.
But once you've tested it and confirmed that the language behaves the way you expect, I wouldn't keep writing tests for that. You can just test the behavior of your code.
Here's a real simple example:
public class TheBaseClass
{
public readonly List<string> Output = new List<string>();
public virtual void WriteToOutput()
{
Output.Add("TheBaseClass");
}
}
public class TheDerivedClass : TheBaseClass
{
public override void WriteToOutput()
{
Output.Add("TheDerivedClass");
base.WriteToOutput();
}
}
Unit test
[TestMethod]
public void EnsureDerivedClassCallsBaseClass()
{
var testSubject = new TheDerivedClass();
testSubject.WriteToOutput();
Assert.IsTrue(testSubject.Output.Contains("TheBaseClass"));
}

How to test virtual methods using Moles?

How can I test the IsHappy function using Moles?
class SomeClass
{
protected virtual bool IsHappy(string mood)
{
return (mood == "Happy");
}
}
I tried to test if by using Stub:
SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));
... but the IsHappyString method returns null thus throwing a NullReference exception.
So, how can I test the default implementation of IsHappy method?
I'd forget about stubs here. Stubs/mocks are for when you want to fake the behavior of a dependency. You'd stub your SomeClass if had SomeClassClient that you wanted to test and it used SomeClass:
public class Foo
{
public virtual int GetFoosInt()
{
return 12;
}
}
public class FooClient
{
private Foo _foo;
public FooClient(Foo foo)
{
_foo = foo;
}
public int AddOneToFoosInt()
{
return _foo.GetFoosInt() + 1;
}
}
In this example, when testing FooClient, what you want to test is that it returns one more than "GetFoosInt()". You don't actually care what FoosInt is for testing the FooClient. So, you create a Foo stub where you can setup GetFoosInt to return whatever you want.
In your case, testing a protected virtual member, I'd go with this:
[TestClass]
public class SomeClassTest
{
private class DummySomeClass : SomeClass
{
public bool IsHappyWrapper(string mood)
{
return IsHappy(mood);
}
}
[TestMethod]
public void SomeTest()
{
var myClass = new DummySomeClass();
Assert.IsTrue(myClass.IsHappyWrapper("Happy"));
}
}
This gives you 'direct' access to the protected virtual to test default behavior. Only word of caution is that if you start defining abstract members and adding to SomeClass in general, you'll have to add them to this dummy inheritor as well, adding to testing maintenance overhead.
The purist in me says that you should leave protected members alone and only test them through the public interface. But, that may or may not be practical in your situation, and I don't really see any harm in this approach.
Stubs and Moles are for isolating a class from any dependencies it has, either environmental dependencies or class dependencies. This class has no dependencies whatsoever, so why are you trying to mole or stub it?
If you want to make sure this base class works properly when people override it, then you'll need to create a test implementation. In that case this is more or less what your test cases should look like:
public SomeClassTestAdapter : SomeClass
{
public bool GetIsHappy(string mood)
{
return IsHappy(mood);
}
}
[Test]
public void ShouldReturnTrueWhenPassedHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("Happy");
Assert.IsTrue(result, "Expected result to be true");
}
[Test]
public void ShouldReturnFalseWhenPassedLowerCaseHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("happy");
Assert.IsFalse(result, "Expected result to be false");
}
[Test]
public void ShouldReturnFalseWhenPassedNull()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy(null);
Assert.IsFalse(result, "Expected result to be false");
}
Etc.
There is no place in this code that stubs or moles should be squeezed in.
If you don't want to create an adapter class for this case, you can use built-in .Net features rather than a big, paid dependency like Moles. Reflections and dynamic let you get access to protected or private members. See this example:
http://igoro.com/archive/use-c-dynamic-typing-to-conveniently-access-internals-of-an-object/

How do I write context/specification style unit tests with an MSTest/xUnit framework?

I have been using MSpec to write my unit tests and really prefer the BDD style, I think it's a lot more readable. I'm now using Silverlight which MSpec doesn't support so I'm having to use MSTest but would still like to maintain a BDD style so am trying to work out a way to do this.
Just to explain what I'm trying to acheive, here's how I'd write an MSpec test
[Subject(typeof(Calculator))]
public class when_I_add_two_numbers : with_calculator
{
Establish context = () => this.Calculator = new Calculator();
Because I_add_2_and_4 = () => this.Calculator.Add(2).Add(4);
It should_display_6 = () => this.Calculator.Result.ShouldEqual(6);
}
public class with_calculator
{
protected static Calculator;
}
So with MSTest I would try to write the test like this (although you can see it won't work because I've put in 2 TestInitialize attributes, but you get what I'm trying to do..)
[TestClass]
public class when_I_add_two_numbers : with_calculator
{
[TestInitialize]
public void GivenIHaveACalculator()
{
this.Calculator = new Calculator();
}
[TestInitialize]
public void WhenIAdd2And4()
{
this.Calculator.Add(2).Add(4);
}
[TestMethod]
public void ThenItShouldDisplay6()
{
this.Calculator.Result.ShouldEqual(6);
}
}
public class with_calculator
{
protected Calculator Calculator {get;set;}
}
Can anyone come up with some more elegant suggestions to write tests in this way with MSTest?
What you think about this one:
[TestClass]
public class when_i_add_two_numbers : with_calculator
{
public override void When()
{
this.calc.Add(2, 4);
}
[TestMethod]
public void ThenItShouldDisplay6()
{
Assert.AreEqual(6, this.calc.Result);
}
[TestMethod]
public void ThenTheCalculatorShouldNotBeNull()
{
Assert.IsNotNull(this.calc);
}
}
public abstract class with_calculator : SpecificationContext
{
protected Calculator calc;
public override void Given()
{
this.calc = new Calculator();
}
}
public abstract class SpecificationContext
{
[TestInitialize]
public void Init()
{
this.Given();
this.When();
}
public virtual void Given(){}
public virtual void When(){}
}
public class Calculator
{
public int Result { get; private set; }
public void Add(int p, int p_2)
{
this.Result = p + p_2;
}
}
Mark Nijhof has an example of doing Given-When-Then style testing with NUnit in his Fohjin.DDD github repository.
Here's an excerpt from the example referenced above:
public class When_registering_an_domain_event : BaseTestFixture<PreProcessor>
{
/* ... */
protected override void When()
{
SubjectUnderTest.RegisterForPreProcessing<ClientMovedEvent>();
SubjectUnderTest.Process();
}
[Then]
public void Then_the_event_processors_for_client_moved_event_will_be_registered()
{
IEnumerable<EventProcessor> eventProcessors;
EventProcessorCache.TryGetEventProcessorsFor(typeof(ClientMovedEvent), out eventProcessors);
eventProcessors.Count().WillBe(1);
}
}
And you can see the Given in the base class implementation:
[Given]
public void Setup()
{
CaughtException = new NoExceptionWasThrownException();
Given();
try
{
When();
}
catch (Exception exception)
{
CaughtException = exception;
}
finally
{
Finally();
}
}
I've been giving this sort of question a lot of though recently. There are a lot of reasonable options out there, and you can create your own easily, as displayed in some of the answers in this post. I've been working on a BDD testing framework with the intent being to make it easily extended to any unit testing framework. I currently support MSTest and NUnit. Its called Given, and it's opensource. The basic idea is pretty simple, Given provides wrappers for common sets of functionality which can then be implemented for each test runner.
The following is an example of an NUnit Given test:
[Story(AsA = "car manufacturer",
IWant = "a factory that makes the right cars",
SoThat = "I can make money")]
public class when_building_a_toyota : Specification
{
static CarFactory _factory;
static Car _car;
given a_car_factory = () =>
{
_factory = new CarFactory();
};
when building_a_toyota = () => _car = _factory.Make(CarType.Toyota);
[then]
public void it_should_create_a_car()
{
_car.ShouldNotBeNull();
}
[then]
public void it_should_be_the_right_type_of_car()
{
_car.Type.ShouldEqual(CarType.Toyota);
}
}
I tried my best to stay true to the concepts from Dan North's Introducting BDD blog, and as such, everything is done using the given, when, then style of specification. The way it is implemented allows you to have multiple givens and even multiple when's, and they should be executed in order (still checking into this).
Additionally, there is a full suite of Should extensions included directly in Given. This enables things like the ShouldEqual() call seen above, but is full of nice methods for collection comparison and type comparison, etc. For those of you familiar with MSpec, i basically ripped them out and made some modifications to make them work outside of MSpec.
The payoff, though, I think, is in the reporting. The test runner is filled with the scenario you've created, so that at a glance you can get details about what each test is actually doing without diving into the code:
Additionally, an HTML report is created using t4 templating based on the results of the tests for each assembly. Classes with matching stories are all nested together, and each scenario name is printed for quick reference. For the above tests the report would look like this:
Failed tests would be colored red and can be clicked to view the exception details.
That's pretty much it. I'm using it in several projects I'm working on, so it is still being actively developed, but I'd describe the core as pretty stable. I'm looking at a way to share contexts by composition instead of inheritance, so that will likely be one of the next changes coming down the pike. Bring on the criticism. :)
You could use NUnit.Specifications and write tests like this:
using NUnit.Specifications;
using Should;
public class OrderSpecs
{
[Component]
public class when_a_customer_places_an_order : ContextSpecification
{
static OrderService _orderService;
static bool _results;
static Order _order;
Establish context = () =>
{
_orderService = new OrderService();
_order = new Order();
};
Because of = () => _results = _orderService.PlaceOrder(_order);
It should_successfully_place_the_order = () => _results.ShouldBeTrue();
}
}
MSTestEnhancer may help you, and you can get the package through NuGet.org.
Here is the sample code:
[TestClass]
public class TheTestedClassTest
{
[ContractTestCase]
public void TheTestedMethod()
{
"When Xxx happens, results in Yyy.".Test(() =>
{
// Write test case code here...
});
"When Zzz happens, results in Www.".Test(() =>
{
// Write test case code here...
});
}
}
And when you see your test result, you'll get this below:
I have written a post to present more information about it. See Introducing MSTestEnhancer to make unit test result easy to read - walterlv for more details.

Testing and mocking private/protected methods. Many posts but still cannot make one example work

I have seen many posts and questions about "Mocking a private method" but still cannot make it work and not found a real answer.
Lets forget the code smell and you should not do it etc....
From what I understand I have done the following:
1) Created a class Library "MyMoqSamples"
2) Added a ref to Moq and NUnit
3) Edited the AssemblyInfo file and added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("MyMoqSamples")]
4) Now need to test a private method.Since it's a private method it's not part of an interface.
5) added the following code
[TestFixture]
public class Can_test_my_private_method
{
[Test]
public void Should_be_able_to_test_my_private_method()
{
// TODO how do I test my DoSomthing method?
}
}
public class CustomerInfo
{
public string Name { get; set; }
public string Surname { get; set; }
}
public interface ICustomerService
{
List<CustomerInfo> GetCustomers();
}
public class CustomerService : ICustomerService
{
public List<CustomerInfo> GetCustomers()
{
return new List<CustomerInfo> { new CustomerInfo { Surname = "Bloggs", Name = "Jo" } };
}
protected virtual void DoSomething()
{
}
}
Could you provide me an example on how you would test my private method?
Thanks a lot
The steps you're describing set Moq up to test internal classes and members so have nothing really to do with testing a protected or private method
Testing private methods is a bit of a smell, you should really test just the public API. If you feel that the method is really important and needs to be tested in isolation perhaps it deserves to be in its own class where it can then be tested on its own?
If your heart is set on testing the protected method above you can roll your own Mock in your test assembly:
public class CustomerServiceMock : CustomerService {
public void DoSomethingTester() {
// Set up state or whatever you need
DoSomething();
}
}
[TestMethod]
public void DoSomething_WhenCalled_DoesSomething() {
CustomerServiceMock serviceMock = new CustomerServiceMock(...);
serviceMock.DoSomethingTester();
}
If it was private you could probably do something dodgy with reflection but going that route is the way to testing hell.
Update
While you've given sample code in your question I don't really see how you want to "test" the protected method so I'll come up with something contrived...
Lets say your customer service looks like this:-
public CustomerService : ICustomerService {
private readonly ICustomerRepository _repository;
public CustomerService(ICustomerRepository repository) {
_repository = repository;
}
public void MakeCustomerPreferred(Customer preferred) {
MakePreferred(customer);
_repository.Save(customer);
}
protected virtual void MakePreferred(Customer customer) {
// Or more than likely some grungy logic
customer.IsPreferred = true;
}
}
If you wanted to test the protected method you can just do something like:-
[TestClass]
public class CustomerServiceTests {
CustomerServiceTester customerService;
Mock<ICustomerRepository> customerRepositoryMock;
[TestInitialize]
public void Setup() {
customerRepoMock = new Mock<ICustomerRepository>();
customerService = new CustomerServiceTester(customerRepoMock.Object);
}
public class CustomerServiceTester : CustomerService {
public void MakePreferredTest(Customer customer) {
MakePreferred(customer);
}
// You could also add in test specific instrumentation
// by overriding MakePreferred here like so...
protected override void MakePreferred(Customer customer) {
CustomerArgument = customer;
WasCalled = true;
base.MakePreferred(customer);
}
public Customer CustomerArgument { get; set; }
public bool WasCalled { get; set; }
}
[TestMethod]
public void MakePreferred_WithValidCustomer_MakesCustomerPreferred() {
Customer customer = new Customer();
customerService.MakePreferredTest(customer);
Assert.AreEqual(true, customer.IsPreferred);
}
// Rest of your tests
}
The name of this "pattern" is Test specific subclass (based on xUnit test patterns terminology) for more info you might want to see here:-
http://xunitpatterns.com/Test-Specific%20Subclass.html
Based on your comments and previous question it seems like you've been tasked with implementing unit tests on some legacy code (or made the decision yourself). In which case the bible of all things legacy code is the book by Michael Feathers. It covers techniques like this as well as refactorings and techniques to deal with breaking down "untestable" classes and methods into something more manageable and I highly recommend it.
There are appear to be two parts to your question.
How do I mock a protected method:
http://blogs.clariusconsulting.net/kzu/mocking-protected-members-with-moq/
how do I trigger the invocation of this protected/private behavior in my test
The answer here is that you trigger it via something public. If you want to force it to happen directly (i.e., actually invoke something protected directly without an intermediate helper, you'll need to use reflection. This is by design - the languages are providing the protection mechanisms as a way of enforcing encapsulation.
I suggest you think about what you're trying to demonstrate/prove in your test though. If you find yourself writing a test that's complicated, you're Doing It Wrong. Perhaps what you want to do can be broken down into independent tests? Perhaps you are writing an integration test, not a unit test? But there are lots of articles out there on bad tests, and more an more will make sense to you as you learn to write good tests. Two of my favourites are http://www.codethinked.com/post/2009/06/30/What-is-Unit-Testing.aspx and http://www.codethinked.com/post/2009/11/05/Ite28099s-Okay-To-Write-Unit-Tests.aspx

Categories

Resources