I want to run the same JUnit tests for different interface implementations. I found a nice solution with the #Parameter option:
public class InterfaceTest{
MyInterface interface;
public InterfaceTest(MyInterface interface) {
this.interface = interface;
}
#Parameters
public static Collection<Object[]> getParameters()
{
return Arrays.asList(new Object[][] {
{ new GoodInterfaceImpl() },
{ new AnotherInterfaceImpl() }
});
}
}
This test would be run twice, first with the GoodInterfaceImpl then with the AnotherInterfaceImpl class. But the problem is I need for most of the testcases a new object. A simplified example:
#Test
public void isEmptyTest(){
assertTrue(interface.isEmpty());
}
#Test
public void insertTest(){
interface.insert(new Object());
assertFalse(interface.isEmpty());
}
If the isEmptyTest is run after the insertTest it fails.
Is there an option to run automatically each testcase with a new instance of an implementation?
BTW: Implementing a clear() or reset()-method for the interface is not really an options since I would not need it in productive code.
Here is another approach with the Template Method pattern:
The interface-oriented tests go into the base class:
public abstract class MyInterfaceTest {
private MyInterface myInterface;
protected abstract MyInterface makeContractSubject();
#Before
public void setUp() {
myInterface = makeContractSubject();
}
#Test
public void isEmptyTest(){
assertTrue(myInterface.isEmpty());
}
#Test
public void insertTest(){
myInterface.insert(new Object());
assertFalse(myInterface.isEmpty());
}
}
For each concrete class, define a concrete test class:
public class GoodInterfaceImplTest extends MyInterfaceTest {
#Override
protected MyInterface makeContractSubject() {
// initialize new GoodInterfaceImpl
// insert proper stubs
return ...;
}
#Test
public void additionalImplementationSpecificStuff() {
...
}
}
A slight advantage over #Parameter is that you get the name of the concrete test class reported when a test fails, so you know right away which implementation failed.
Btw, in order for this approach to work at all, the interface must be designed in a way which allows testing by the interface methods only. This implies state-based testing -- you cannot verify mocks in the base test class. If you need to verify mocks in implementation-specific tests, these tests must go into the concrete test classes.
Create a factory interface and implementations, possibly only in your test hierarchy if you don't need such a thing in production, and make getParameters() return a list of factories.
Then you can invoke the factory in a #Before annotated method to get a new instance of your actual class under test for each test method run.
Just in case somebody reaches here(like I did), looking for testing multiple implementations of the same interface in .net you could see one of the approaches that I was using in one of the projects here
Below is what we are following in short
The same test project dll is run twice using vstest.console, by setting an environment variable. Inside the test, (either in the assembly initialize or test initialize) register the appropriate implementations into a IoC container, based on the environment variable value.
In Junit 5 you could do:
#ParameterizedTest
#MethodSource("myInterfaceProvider")
void test(MyInterface myInterface) {}
static Stream<MyInterface> myInterfaceProvider() {
return Stream.of(new ImplA(), new ImplB());
}
interface MyInterface {}
static class ImplA implements MyInterface {}
static class ImplB implements MyInterface {}
Related
I have to write an integration test and I have service like below
public class MyService: IMyService
{
private readonly ISecureStorage secureStorageService;
public MyService(ISecureStorage secureStorageService)
{
this.secureStorageService = secureStorageService;
}
}
How do I create an implementation of ISecureStorage in my test?
ISecureStorage mySecureStorage = new ???????
You can create a test implementation for it or use a mock, since you don't want to test the real SecureStorage class (you can't, really, without a lot of platform specific fuzz).
Option 1: Use the Moq library:
using Moq;
public class MyTests
{
// this conveniently takes care of the mock implementation for you
private Mock<ISecureStorage> _secureStorageMock = new Mock<ISecureStorage>();
[Test]
public void Example()
{
//arrange
var myService = new MyService(_secureStorageMock.object);
//act
myService.DoSomething();
//assert
Assert.IsTrue(myService.Whatever);
// You can also check if a specific method has been called, like below
_secureStorageMock.Verify(s => s.SetAsync(It.IsAny<string>(), It.IsAny<string>());
}
}
Option 2: Create a stub implementation:
public class FakeStorage : ISecureStorage
{
//TODO: implement interface with stub methods that don't actually do anything useful
}
Then use it in your test:
public class MyTests
{
[Test]
public void Example()
{
//arrange
var myService = new MyService(new FakeStorage());
//act
myService.DoSomething();
//assert
Assert.IsTrue(myService.Whatever);
}
}
These are just two ways to do it. More advanced scenarios could involve an inversion of control container. Also, I'm just assuming the use of NUnit here, but the same goes for xUnit, too.
I recommend approach no. 1. It's easier, more powerful and avoids writing a fake or stub implementation.
An experimental/theoretical question concerning any OOP language (Java, C#, Typescript, etc..)
Usually, when implementing an interface in a class, one has to override all the functions of that interface in the class by having to write the code for each function from that interface. And every class that implements this interface has to have its own code for those functions. Suppose we have an interface called Test that has a function called foo() in which I want the following code System.out.println("This is an interface function");.Usually one has to make an interface and declare the function and then writes the code in every implementing class
But what if there is some "theoretical" way of having all of the function written in the interface and every implementing class can just call it without having to override. Something like the following (using Java as a base language):
interface Test {
public foo() {
System.out.println("Test log.")
}
}
class Class1 implements Test {
constructor() {}
}
class Class2 implements Test {
constructor() {}
}
class Main {
public static void main() {
Class1 f1 = new Class1();
Class2 f2 = new Class2();
f1.foo();
f2.foo();
}
}
Java has this feature since Java 8. Interfaces can have default implementations where the class is free to override them, but not required to do so.
interface Test {
default void foo() {
System.out.println("Test log.");
}
}
I had following code
public interface IFoo
{
void Execute();
}
public abstract class FooBar: IFoo
{
public void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
and following test case to test the Execute() method
[Fact]
public void When_execute_method_called_Expect_executionTime_is_set()
{
var sutMethod = A.Fake<FooBar>();
A.CallTo(sutMethod).
Where(x => x.Method.Name == "OnExecute").
Invokes(x => Thread.Sleep(100)));
sutMethod.Execute();
Assert.NotEqual(0, sutMethod.Result.ExecutionTime.Ticks);
}
sutMethod.Execute(); call would go to FooBar.Execute()
later I decided to make the interface into an abstract class
public abstract class IFoo
{
public abstract void Execute();
}
public abstract class FooBar:IFoo
{
public override void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
Now sutMethod.Execute(); call does not invoke FooBar.Execute()
I thought FakeItEasy would handles interface and abstract classes as equal.What am I missing?
Update
# Blair Conrad provided the reasoning for the behaviour
Is it possible to make minimal changes to the test case to get the original behaviour back?
thanks
The difference is due to the overrideability of the method Execute on FooBar.
FakeItEasy can only override virtual members, abstract members, or interface members.
In your original example, when IFooBar is an interface and FooBar implements it, Execute is a concrete method. It's not virtual, nor is it abstract. Thus FakeItEasy can't intercept calls to it, and the original method is executed.
Once you change IFooBar to an abstract class, you have an abstract IFooBar.Execute, which you override in FooBar. As such, FooBar.Execute is now virtual and can be intercepted by FakeItEasy. Which it does, so your implementation is not called.
Following addition help solve the issue
A.CallTo(() => sutMethod.Execute()).CallsBaseMethod();
This calls the virtual method Executeof FooBar
I have a JUnit test that I run on one class, but I recently wrote an emulated version for GWT. Since the specification is the same, I would like to use the same test case, but I want it to run in the GWT environment, which would typically be accomplished by extending GWTTestCase.
I really want to avoid any copy/paste nonsense, because there are likely to be added tests in the future, which I should not be burdened with copying later.
How can I import/inherit my standard unit test to be run as either a regular test case or a GWT test case?
I have found the solution to this problem.
If you extend the original test with GWTTestCase, you can override getModuleName to return null. This tells GWTTestCase to run as a normal pure java test (no translation at all).
You can then extend this test case with one that overrides getModuleName to return a module name, and the same tests will be run with translation.
Basically:
public class RegularTest extends GWTTestCase {
#Override
public String getModuleName() { return null; }
public void testIt() {...}
}
...and the GWT version...
public class GwtTest extends RegularTest {
#Override
public String getModuleName() { return "some.module"; }
}
The downside to this is that it forces you to use JUnit3 style tests, which I find a little annoying, but it beats the alternative.
I think there is no easy way .. But you can extract an interface of your junit test, gwt test case and junit test case implements this interface. You can create a third class for implementation, all test call methods of gwt test case and junit test are delegated to this implementation class.
public interface IRegularTest {
public void testSomething();
public void testSomething2();
}
public class RegularTestImpl implements IRegularTest {
public void testSomething(){
// actual test code
}
public void testSomething2(){
// actual test code
}
}
public class RegularTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}
public class GwtTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}
If I have the following code:
[TestFixture]
public class MyBaseTest
{
protected ISessionManager _sessionManager;
[SetUp]
public void SetUp() { /* some code that initializes _sessionManager */ }
}
[TestFixture]
public class MyDerivedTest : MyBaseTest
{
IBlogRepository _repository;
[SetUp]
public void SetUp() { /* some code that initializes _repository */ }
[Test]
public void BlogRepository_TestGoesHere() { /* some tests */ }
}
...NUnit doesn't call the base SetUp routine. This is expected, and I don't have a problem with it in itself. I can get the derived SetUp to call the base SetUp first, like this:
[TestFixture]
public class MyDerivedTest : MyBaseTest
{
IBlogRepository _repository;
[SetUp]
public new void SetUp()
{
base.SetUp();
/* some code that initializes _repository */
}
This is ugly. If it was a constructor, I wouldn't have to.
I could use the "template method" pattern, and have the following:
public void MyBaseTest
{
abstract void SetUp();
[SetUp]
public void BaseSetUp()
{
/* base initialization */
SetUp(); // virtual call
}
}
I'm not particularly fond of this, either.
What do you do when their test classes need SetUp, and they're derived from another class that also needs SetUp?
You have to call the method directly.
[SetUp]
public void DerivedSetUp()
{
base.BaseSetUp();
// Do something else
}
Edit: I haven't tried it, but perhaps a partial method might work too. I'd prefer to do the above though.
Edit2: I've just tried using partial methods. It didn't work. Even if it did, I think it's still going to be easier to call the base class.
You have the base class explicitly. Given that NUnit uses the [Setup] attribute to mark up test setup, I tink this is "the right thing" to do for NUnit, because it follows the usual language rules.
Sure, NUnit could search the base classes, and call their Setup functions automagically, but I think this would be rather surprising for most people.
There is however at least one unit testing framework that uses constructors for setup: xUnit.Net. Here, the base class setup is called automatically, because this is how constructors in C# behave.
(Note, though, that xUnit.Net recommends again using test setup.)
It looks like you want the setup to be run once before any testing starts, not once before each test is run. The annotation [SetUp] makes the method run once before each test in your fixture is run. [SetUp] is not inherited.
The annotation you want to use is [TestFixtureSetUp] which is run only once, before any of the tests in a fixture are run. This is inherited in the way that you would expect. :)
See the TextFixtureSetUp docs
An approach that I use that I learned in the TDD FireStarter in Tampa was to have the setup method in the base class and then to have a virtual method in the base class called observe. This method is then called in the base class at the end of the setup method.
Then what you do is in the new class that derives from the base class you will override the observe method. The trick in this scenario is you want to execute the Setup method of the base class and the child class does not have a Setup method. The reason for this is the code that you have in the observe method are only those additional things you need for the child test class.
This approach works well for me, but one gotcha is that the test runner will want to execute the base class tests, so what I do to get around that is to move the Tests from the base class into a new class that derives from the base if I have any.
The following works in MbUnit. It may work in NUnit as well.
[TestFixture]
public abstract class Base {
[SetUp]
public virtual void SetUp() {
//Some stuff.
}
}
public class Derived : Base {
public override void SetUp() {
base.SetUp();
//Some more stuff.
}
[Test]
public virtual void Object_WhenInACertainState_WhenAMethodIsCalled_Throws() {
//Create and set state on the object.
//Call the method.
//Assert the method threw.
}
}