First of all I'm a beginner in unit tests. For my tests i want to use NSubstitute, so I read the tutorial on the website and also the mock comparison from Richard Banks. Both of them are testing against interfaces, not against classes. The statement is "Generally this [substituted] type will be an interface, but you can also substitute classes in cases of emergency."
Now I'm wondering about the purpose of testing against interfaces. Here is the example interface from the NSubstitute website (please note, that i have converted the C#-code in VB.net):
Public Interface ICalculator
Function Add(a As Double, b As Double) As Double
Property Mode As String
Event PoweringUp As EventHandler
End Interface
And here is the unit test from the website (under the NUnit-Framework):
<Test>
Sub ReturnValue_For_Methods()
Dim calculator = Substitute.For(Of ICalculator)()
calculator.Add(1, 2).Returns(3)
Assert.AreEqual(calculator.Add(1, 2), 3)
End Sub
Ok, that works and the unit test will perform successful. But what sense makes this? This do not test any code. The Add-Method could have any errors, which will not be detected when testing against interfaces - like this:
Public Class Calculator
Implements ICalculator
Public Function Add(a As Double, b As Double) As Double Implements ICalculator.Add
Return 1 / 0
End Function
...
End Class
The Add-Method performs a division by zero, so the unit test should fail - but because of testing against the interface ICalculator the test is successful.
Could you please help me to understand that? What sense makes it, not to test the code but the interface?
Thanks in advance
Michael
The idea behind mocking is to isolate a class we are testing from its dependencies. So we don't mock the class we are testing, in this case Calculator, we mock an ICalculator when testing a class that uses an ICalculator.
A small example is when we want to test how something interacts with a database, but we don't want to use a real database for some quick tests. (Please excuse the C#.)
[Test]
public void SaveTodoItemToDatabase() {
var substituteDb = Substitute.For<IDatabase>();
var todoScreen = new TodoViewModel(substituteDb);
todoScreen.Item = "Read StackOverflow";
todoScreen.CurrentUser = "Anna";
todoScreen.Save();
substituteDb.Received().SaveTodo("Read StackOverflow", "Anna");
}
The idea here is we've separated the TodoViewModel from the details of saving to the database. We don't want to worry about configuring a database, or getting a connection string, or having data from previous test runs interfering with future tests runs. Testing with a real database can be very valuable, but in some cases we just want to test a smaller unit of functionality. Mocking is one way of doing this.
For the real app, we'll create a TodoViewModel with a real implementation of IDatabase, and provided that implementation follows the expected contract of the interface then we can have a reasonable expectation that it will work.
Hope this helps.
Update in response to comment
The test for TodoViewModel assumes the implementation of the IDatabase works so we can focus on that class' logic. This means we'll probably want a separate set of tests for implementations of IDatabase. Say we have a SqlServerDbimplementation, then we can have some tests (probably against a real database) that check it does what it promises. In those tests we'll no longer be mocking the database interface, because that's what we're testing.
Another thing we can do is have "contract tests" which we can apply to any IDatabase implementation. For example, we could have a test that says for any implementation, saving an item then loading it up again should return the same item. We can then run those tests against all implementations, SqlDb, InMemoryDb, FileDb etc. In this way we can state our assumptions about the dependencies we're mocking, then check that the actual implementations meet our assumptions.
Related
It seems like all of the Mockito examples I have looked at, "fake" the behavior of the object they are testing.
If I have an object that has a the method:
public int add(int a, int b) {return a+b}
I would simply use JUnit to assert whether two integers passed in would result in the correct output.
With all of the examples I've seen with Mockito, people are doing things like when.Object.add(2,3).thenReturn(5). What's the point of using this testing framework, if all you're doing is telling the object how to act on the test side, rather than the object side?
Mocking frameworks are good for testing a system by mocking that system's dependencies; you wouldn't use a mocking framework to mock or stub add if you are testing add. Let's break this out a bit further:
Testing add
A mocking framework is not good for testing your add method above. There are no dependencies other than the very stable and extremely-well-tested JVM and JRE.
public int add(int a, int b) {return a+b}
However, it might be good for testing your add method if it were to interact with another object like this:
public int add(int a, int b, AdditionLogger additionLogger) {
int total = a + b;
additionLogger.log(a, b, total);
return total;
}
If AdditionLogger isn't written yet, or if it's written to communicate with a real server or other external process, then a mocking framework would absolutely be useful: it would help you come up with a fake implementation of AdditionLogger so you could test your real method's interactions with it.
#Test public void yourTest() {
assertEquals(5, yourObject.add(2, 3, mockAdditionLogger));
verify(mockAdditionLogger).log(2, 3, 5);
}
Testing add's consumers
Coincidentally, a mocking framework is also unlikely to be good for testing consumers of your method above. After all, there is nothing particularly dangerous about a call to add, so assuming it exists you can probably call the real one in an external test. 2 + 3 will always equal 5, and there are no side effects from your calculation, so there's very little to be gained by mocking or verifying.
However, let's give your object another method that adds two numbers with a little bit of random noise:
public int addWithNoise(int a, int b) {
int offset = new Random().nextInt(11) - 5; // range: [-5, 5]
int total = a + b + offset;
return total;
}
With this, it may be very hard for you to write a robust assert-style test against this method; after all, the result is going to be somewhat random! Instead, to make an assert-style test easier, maybe we can stub out addWithNoise to make some of this more predictable.
#Test public void yourTest() {
when(yourObjectMock.addWithNoise(2, 3)).thenReturn(6);
// You're not asserting/verifying the action you stub, you're making the dependency
// *fast and reliable* so you can check the logic of *the real method you're testing*.
assertEquals(600, systemUnderTestThatConsumesYourObject.doThing(yourObjectMock));
}
In summary
It can be easier to explain mocking and mock syntax when interacting with well-known operations like add or well-known interfaces like List, but those examples are not usually realistic cases where mocks are needed. Remember that mocking is only really useful for simulating the dependencies around your system-under-test when you can't use real ones.
Goal of unit-testing is to test the functionality without connecting to any external systems. If you are connecting to any external system, that is considered integration testing.
While performing unit-testing, a system may need some data that could have been retrieved from external systems as database, web/rest services, API etc during Systems/Integration testing. In such scenarios, we need to supply mock/fake data to test some business rules, or any other form of logic.
With above, unit-tests ensure that a particular unit of code works with given set of fake/mocked data, and should behave in similar manner in integrated environment.
I'm trying to rebuild some old QBASIC (yeah, you read that right) programs for use on more modern systems (because for some reason kids these days don't like DOS).
I understand the basic principles of classes and objects (I think) but I'm obviously missing something.
I have a number of instruments which are controlled using GPIB, using VISA COM libraries. I can make it work, but the code is very ugly :(
In order to use an instrument, I have the following in my Public Class Main:
Public ioMgr As Ivi.Visa.Interop.ResourceManager
Dim myInstrument As New Ivi.Visa.Interop.FormattedIO488
Dim myInstOpen As Boolean
Then, when I come to initializing the instrument (in the 'Initialize' button click sub), I use:
Try
myInstrument.IO = ioMgr.Open("GPIB0::17")
Catch exOpen As System.Runtime.InteropServices.COMException
myInstOpen = False
End Try
Pretty straightforward stuff; if the instrument can't be opened at address 17 on GPIB0, it throws an exception, which gets caught and sets the 'myInstOpen' flag to false.
Then, I can communicate with the instrument using commands from the Ivi.Visa.Interop.FormattedIO488 interface such as:
myInstrument.IO.ReadSTB()
result = myInstrument.ReadString()
myInstrument.WriteString("GPIB Command Here")
And all of it works.
What I want to do is, create a generic 'Instrument' class, that allows me access to all the functions from the Ivi.Visa.Interop.FormattedIO488 interface, and from the Ivi.Visa.Interop.ResourceManager interface, but also allows me to build my own class.
For instance:
Public Class GPIBInst
Implements Ivi.Visa.Interop.FormattedIO488
Public Address As Integer
Public Sub setAddress(ByVal Addr As Integer)
Address = Addr
End Sub
Public Function getAddress() As Integer
Return Address
End Function
Public Function readIO() As String
Dim Data As String = me.ReadString()
Dim Result As String = mid(Data,2,7)
Return Result
End Function
End Class
This would allow me to use the functions from the interface, but also customize the instruments for other useful things inside the program. For instance, the GPIBInst.Address needs to be used in other places, and the GPIBInst.readIO() can be used instead of just the generic ReadString() so that I can customize the output a little.
BUT when I try to do this, I can't inherit from the interface (because it's an interface) and I can't implement the interface because it says my class needs to implement every single function which the interface provides. I don't want all these functions, and also, I can't work out how to write them all into my class anyway (they have heaps of random stuff in them which I don't understand lol).
If anyone can see where I'm coming from and can offer some advice, I'd really appreciate it =)
An interface is supposed to represent a coherent set of functionality; implementing part of it but not all of it violates the intent of the concept. That being said, it is very common for APIs in object-oriented languages that wrap non-OO systems to just define one massive interface rather than breaking the functionality into logical sub-groups and defining an interface for each group. If that is your circumstance, and you want to implement the interface, you have no choice but to implement every method from the interface (although you can throw a NotImplementException for any method that you don't want to fully implement, as long as that will not prevent your class from functioning properly).
I am new to the unit testing project and I am wondering how I can create and use a database connection. Can someone offer a VB.Net example? It seems most are in c#
This is as far as I have got! The function GetCorrectedTransactionEffectiveDate expects a connection object as it looks up some goodies in the database
So I am a little bewildered as to how this should be done in unit testing??
<TestClass()> Public Class UnitTest1
<DataSource ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\BServer\bucshared\Systems\ApplicationData\BOne\ENV_DEV\Database\BOne.accdb; Jet OLEDB:Database Password=password"), ]
<TestMethod()> Public Sub RecordedDateTest()
Dim DateToday As New Date(2014, 6, 14)
Dim TransactionDate As New Date(2014, 7, 15)
Dim oUtil As New BerkleyOne.clsDbUtil({Database connection})
Dim Res as date = oUtil.GetCorrectedTransactionEffectiveDate(TransactionDate)
End Sub
End Class
TL;DR I don't think the DataSourceAttribute is what you want.
According to the class's documentation, its purpose is to identify a data store for inputs to the test method.
So in your case, the way you'd want to use this would be to:
have the test method accept a Date (or DateTime) parameter
pass that parameter to oUtil.GetCorrectedTransactionEffectiveDate()
store the set of input parameter values in a database
use the DataSourceAttribute would identify how to locate the test input values
... but (from what I can tell) this would be more of an integration test than a unit test.
To be able to unit test your code, your code should follow the Single Responsibility Principle. But it appears the GetCorrectedTransactionEffectiveDate() method is doing at least two things:
looking up information in a database (perhaps weekend days and holidays);
performing some sort of date calculations.
As I noted in a comment, in the world of automated testing -- which appears to be your goal -- a unit test is supposed to test code (naturally), and be able to do so quickly. Therefore, you don't want the code you're unit testing to be performing network, database, or even disk I/O.
A common approach would be to separate the date-calculation logic and database access as follows:
define an interface for the data-retrieval mechanism (GetFooById(), GetFooByName(), etc.) -- this is commonly referred to as a "repository";
implement the repository interface with a "real" class that fetches the values from a database / web service / whatever;
implement the interface with a mock class that (for example) always returns a hard-coded value, or collection of values;
better yet, create the mock implementation using a mocking framework -- this will allow you to construct the mock object and specify what it should return in your test method ("on the fly");
modify clsDbUtil to accept an IFooRepository as a constructor parameter (rather than a connection string) and delegate all the data-retrieval work to the repository.
Now you have a test for your date calculation that should run in at most a few milliseconds. So the next time a "Y2K" type calendar altering event occurs, you'll be able to quickly verify (regression test) any changes you have to make to the date calculations.
An additional benefit is that the repository interface is (or should be) media-agnostic. If you have to go from a database to XML or JSON files or a web service, none of the date calculation code should be affected.
I realize all this isn't trivial. And it's not always feasible to modify the source code for clsDbUtil or whatever. You can still test the method; again, it'll be more of an integration test, but (as comments have noted) that's still much better than no tests at all.
Automated testing (unit / integration / acceptance testing) is a large topic;I've only scratched the surface here.
Assuming I haven't frightened you away, I would recommend you read Roy Osherove's The Art of Unit Testing. If you're working with a code base that doesn't lend itself (easily) to automated testing, I'd also recommend Michael Feathers' Working Effectively with Legacy Code.
A method can be tested either with mock object or without. I prefer the solution without mock when they are not necessary because:
They make tests more difficult to understand.
After refactoring it is a pain to fix junit tests if they have been implemented with mocks.
But I would like to ask your opinion. Here the method under test:
public class OndemandBuilder {
....
private LinksBuilder linksBuilder;
....
public OndemandBuilder buildLink(String pid) {
broadcastOfBuilder = new LinksBuilder(pipsBeanFactory);
broadcastOfBuilder.type(XXX).pid(pid);
return this;
}
Test with mocks:
#Test
public void testbuildLink() throws Exception {
String type = "XXX";
String pid = "test_pid";
LinksBuilder linkBuilder = mock(LinksBuilder.class);
given(linkBuilder.type(type)).willReturn(linkBuilder);
//builderFactory replace the new call in order to mock it
given(builderFactory.createLinksBuilder(pipsBeanFactory)).willReturn(linkBuilder);
OndemandBuilder returnedBuilder = builder.buildLink(pid);
assertEquals(builder, returnedBuilder); //they point to the same obj
verify(linkBuilder, times(1)).type(type);
verify(linkBuilder, times(1)).pid(pid);
verifyNoMoreInteractions(linkBuilder);
}
The returnedBuilder obj within the method buildLink is 'this' that means that builder and returnedBuilder can't be different because they point to the same object in memory so the assertEquals is not really testing that it contains the expected field set by the method buildLink (which is the pid).
I have changed that test as below, without using mocks. The below test asserts what we want to test which is that the builder contains a LinkBuilder not null and the LinkBuilder pid is the one expected.
#Test
public void testbuildLink() throws Exception {
String pid = "test_pid";
OndemandBuilder returnedBuilder = builder.buildLink(pid);
assertNotNull(returnedBuilder.getLinkBuilder());
assertEquals(pid, returnedBuilder.getLinkBuilder().getPid());
}
I wouldn't use mock unless they are necessary, but I wonder if this makes sense or I misunderstand the mock way of testing.
Mocking is a very powerful tool when writing unit tests, in a nut shell where you have dependencies between classes, and you want to test one class that depends on another, you can use mock objects to limit the scope of your tests so that you are only testing the code in the class that you want to test, and not those classes it depends on. There is no point me explaining further, I would highly recommend you read the brilliant Martin Fowler work Mocks Aren't Stubs for a full introduction into the topic.
In your example, the test without mocks is definitely cleaner, but you will notice that your test exercises code in both the OndemandBuilder and LinksBuilder classes. It may be that this is what you want to do, but the 'problem' here is that should the test fail, it could be due to issues in either of those two classes. In your case, because the code in OndemandBuilder.buildLink is minimal, I would say your approach is OK. However, if the logic in this function was more complex, then I would suggest that you would want to unit test this method in a way that didn't depend on the behavior of the LinksBuilder.type method. This is where mock objects can help you.
Lets say we do want to test OndemandBuilder.buildLink independent of the LinksBuilder implementation. To do this, we want to be able to replace the linksBuilder object in OndemandBuilder with a mock object - by doing this we can precisely control what is returned by calls to this mock object, breaking the dependency on the implementation of LinksBuilder. This is where the technique Dependency Injection can help you - the example below shows how we could modify OndemandBuilder to allow linksBuilder to be replaced with a mock object (by injecting the dependency in the constructor):
public class OndemandBuilder {
....
private LinksBuilder linksBuilder;
....
public class OndemandBuilder(LinksBuilder linksBuilder) {
this.linksBuilder = linksBuilder;
}
public OndemandBuilder buildLink(String pid) {
broadcastOfBuilder = new LinksBuilder(pipsBeanFactory);
broadcastOfBuilder.type(XXX).pid(pid);
return this;
}
}
Now, in your test, when you create your OndemandBuilder object, you can create a mock version of LinksBuilder, pass it into the constructor, and control how this behaves for the purpose of your test. By using mock objects and dependency injection, you can now properly unit test OndemandBuilder independent of the LinksBuilder implementation.
Hope this helps.
It all dependent upon what you understand by UNIT testing.
Because when you are trying to unit test a class , it means you are not worried about the underlying system/interface. You are assuming they are working correctly hence you just mock them. And when i say you are ASSUMING means you are unit testing the underlying interface separately.
So when you are writing your JUnits without mocks essentially you are doing a system or an integration test.
But to answer your question both ways have their advantages/disadvantages and ideally a system should have both.
I'm (somewhat) new to DI and am trying to understand how/why it's used in the codebase I am maintaining. I have found a series of classes that map data from stored procedure calls to domain objects. For example:
Public Sub New(domainFactory As IDomainFactory)
_domainFactory = domainFactory
End Sub
Protected Overrides Function MapFromRow(row As DataRow) As ISomeDomainObject
Dim domainObject = _domainFactory.CreateSomeDomainObject()
' Populate the object
domainObject.ID = CType(row("id"), Integer)
domainObject.StartDate = CType(row("date"), Date)
domainObject.Active = CType(row("enabled"), Boolean)
Return domainObject
End Function
The IDomainFactory is injected with Spring.Net. It's implementation simply has a series of methods that return new instances of the various domain objects. eg:
Public Function CreateSomeDomainObject() As ISomeDomainObject
Return New SomeDomainObject()
End Function
All of the above code strikes me as worse than useless. It's hard to follow and does nothing of value. Additionally, as far as I can tell it's a misuse of DI as it's not really intended for local variables. Furthermore, we don't need more than one implementation of the domain objects, we don't do any unit testing and if we did we still wouldn't mock the domain objects. As you can see from the above code, any changes to the domain object would be the result of changes to the SP, which would mean the MapFromRow method would have to be edited anyway.
That said, should I rip this nonsense out or is it doing something amazingly awesome and I'm missing it?
The idea behind dependency injection is to make a class (or another piece of code) independent on a specific implementation of an interface. The class outlined above does not know which class implements IDomainFactory. A concrete implementation is injected through its constructor and later used by the method MapFromRow. The domain factory returns an implementation of ISomeDomainObject which is also unknown.
This allows you supplement another implementation of these interfaces without having to change the class shown above. This is very practical for unit tests. Let's assume that you have an interface IDatabase that defines a method GetCustomerByID. It is difficult to test code that uses this method, since it depends on specific customer records in the database. Now you can inject a dummy database class that returns customers generated by code that does not access a physical database. Such a dummy class is often called a mock object.
See Dependency injection on Wikipedia.