How to mock method call from other class in Rhino Mock AAA? - rhino-mocks

I have the following code(simplified).
public class OrderProcessor
{
public virtual string PlaceOrder(string test)
{
OrderParser orderParser = new OrderParser();
string tester = orderParser.ParseOrder(test);
return tester + " here" ;
}
}
public class OrderParser
{
public virtual string ParseOrder(string test)
{
if (!string.IsNullOrEmpty(test.Trim()))
{
if (test == "Test1")
return "Test1";
else
{
return "Hello";
}
}
else
return null;
}
}
My test is as follows -
public class OrderTest
{
public void TestParser()
{
// Arrange
var client = MockRepository.GenerateMock<OrderProcessor>();
var spec = MockRepository.GenerateStub<OrderParser>();
spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1");
//How to pass spec to client so that it uses the same.
}
}
Now how do I test client so that it uses the mocked method from OrderParser.
I can mock the OrderParser but how do I pass that to the orderProcessor mocked class?
Please do let me know.
Thanks in advance.

I'm a little confused by your test since you are not really testing anything except that RhinoMocks works. You create two mocks and then do some assertions on them. You haven't even tested your real classes.
You need to do some dependency injection if you really want to get a good unit test. You can quickly refactor your code to use interfaces and dependency injection to make your test valid.
Start by extracting an interface from your OrderParser class:
public interface IOrderParser
{
String ParseOrder(String value);
}
Now make sure your OrderParser class implements that interface:
public class OrderParser: IOrderParser{ ... }
You can now refactor your OrderProcessor class to take in an instance of an IOrderParser object through its constructor. In this way you "inject" the dependency into the class.
public class OrderProcessor
{
IOrderParser _orderParser;
public OrderProcessor(IOrderParser orderParser)
{
_orderParser = orderParser;
}
public virtual string PlaceOrder(string val)
{
string tester = _orderParser.ParseOrder(val);
return tester + " here" ;
}
}
In your test you only want to mock out the dependency and not the SUT (Subject Under Test). Your test would look something like this:
public class OrderTest
{
public void TestParser()
{
// Arrange
var spec = MockRepository.GenerateMock<IOrderParser>();
var client = new OrderProcessor(spec);
spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1");
//Act
var s = client.PlaceOrder("Blah");
//Assert
Assert.AreEqual("Test1 Here", s);
}
}
It is difficult for me to gauge what you are trying to do with your classes, but you should be able to get the idea from this. A few axioms to follow:
Use interfaces and composition over inheritance
Use dependency injection for external dependencies (inversion of control)
Test a single unit, and mock its dependencies
Only mock one level of dependencies. If you are testing class X which depends on Y which depends on Z, you should only be mocking Y and never Z.
Always test behavior and never implementation details
You seem to be on the right track, but need a little guidance. I would suggest reading material that Martin Fowler, and Bob Martin have to get up to speed.

Related

PHPUnit testing a protected static method that uses pdo

I am very new to TDD. I am using phpunit 7.4x-dev. I have the following abstract class that I am trying to develop unit tests for.
use PDO;
abstract class Model {
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new PDO(ConfigDatabase::DSN, ConfigDatabase::USER, ConfigDatabase::PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return $db;
}
}
I have created the following test to get around the need to deal with the static protected method. And it works if I provide "ConfigureDatabase" class.
use PHPUnit\Framework\TestCase;
class ModelTest extends TestCase {
function newMockClass(){
$stub = new class() extends Model{
function getStaticMethod($methodName){
return self::$methodName();
}
};
return $stub;
}
public function testDatabaseExists() {
$stub = $this->newMockClass();
$db = $stub->getStaticMethod('getDB');
$this->assertInstanceOf(PDO::class,$db);
}
}
Since I do not want my tests to rely on any actual database, How would I fake the calls to PDO.
Following Dormilich suggestion I developed a database interface, just in case I decide later I do not want to use PDO.
interface CRUDImp {
function __construct($datbaseBridgeLikePDO);
...
}
Next I wrote my tests for the constructor. I used setup to make sure I was starting with a fresh mock of \PDO.
class PDOWrapperTest extends TestCase {
private $pdoMock;
private $db;
function setup() {
$this->pdoMock = $this->createMock('\PDO');
$this->db = new PDOWrapper($this->pdoMock);
}
public function testWrapperExists() {
$this->pdoMock->method('getAttribute')->willReturn(\PDO::ERRMODE_EXCEPTION);
$db = new PDOWrapper($this->pdoMock);
$x = $db instanceof CRUDImp;
$this->assertTrue($x);
}
/**
* #expectedException \Exception
*/
public function testNonPDOPassedToConstructor() {
$mock = $this->createMock('\Exception');
$x = new PDOWrapper($mock);
}
...
}
Since PHP is loosely typed I check to make sure that the class passed to the constructor was an instance of \PDO. I implemented the concrete class as follows
class PDOWrapper implements CRUDImp {
private $pdo;
private $dataOutputType = \PDO::FETCH_ASSOC;
public function __construct($pdo) {
if (!($pdo instanceof \PDO)) {
throw new \Exception("PDOWrapper must be passed instance of \PDO");
}
$attr_Errmode = $pdo->getAttribute(\PDO::ATTR_ERRMODE);
if ($attr_Errmode !== \PDO::ERRMODE_EXCEPTION) {
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
$this->pdo = $pdo;
}
...
}
Now that I have an independent database wrapper the original Model tests are at the moment trivial and no longer needed. The abstract class Model was modified as follows:
abstract class Model {
protected $database=null;
function __construct(CRUDWrapper $database) {
$this->database = $database;
}
...
}
So for those not familiar with dependency injection I found the following links helpful:
http://php-di.org/doc/understanding-di.html
https://codeinphp.github.io/post/dependency-injection-in-php/
https://designpatternsphp.readthedocs.io/en/latest/Structural/DependencyInjection/README.html
Hope this shortens someone's work.

NSubstitute: Received Calls asserts wrongly

I've created this test:
[TestFixture]
public class UsersTests
{
private Core.Kernel coreKernel;
private Core.Configuration.ICoreConfiguration coreConfiguration;
[SetUp]
public void SetUp()
{
this.coreConfiguration = NSubstitute.Substitute.For<Core.Configuration.ICoreConfiguration>();
this.coreKernel = NSubstitute.Substitute.For<Core.Kernel>(this.coreConfiguration);
this.coreKernel.Initialize();
}
[Test]
public void AddUserTest()
{
Core.Communication.Entities.UserIdentity receivedUserIdentity = new Core.Communication.Entities.UserIdentity("user1", "passwd1");
((Core.Communication.ICoreService)this.coreKernel).AddUserIdentity(receivedUserIdentity);
this.coreKernel.Received(100).AddUser(Arg.Is<Core.Identity.UserIdentity>(u => u.UserId.Equals(receivedUserIdentity.UserId)));
}
}
where Core.Kernel is:
public partial class Kernel : Core.IKernel
{
public Kernel(Configuration.ICoreConfiguration configuration)
: this(configuration, null, Enumerable.Empty<Type>())
{
}
public Kernel(Configuration.ICoreConfiguration configuration, Communication.ICoreService service, IEnumerable<Type> producerTypes)
{
if (configuration == null)
throw new ArgumentException("configuration object must be provided", "configuration");
if (producerTypes.Any(t => !t.IsAssignableFrom(typeof(Core.Extensibility.AbstractProducerPlugin))))
throw new ArgumentException("All types must inherit from AbstractProducerPlugin", "plugins");
this.state = KernelState.initializing;
this.configuration = configuration;
this.service = service ?? this;
this.producerTypes = producerTypes;
this.backends = new Dictionary<Core.Identity.DomainIdentity, Backend.Infrastructure.IBackend>();
}
internal virtual void AddUser(Core.Identity.UserIdentity userIdentity) {...}
}
Nevertheless, this.coreKernel.Received(100).AddUser(... is not called 100 times, only one. What am I doing wrong?
I mean, I'm not trying to make 100 calls to AddUser. I'm checking AddUser should be called 100 times. So, assertion should fail.
EDIT
Guess this code (Core.IKernel.AddUserIdentity(...) implementation):
public class Core.Kernel {
public override void Core.IKernel.AddUserIdentity(UserIdentity userIdentity) {
this.AddUser(userIdentity); <<----- AddUser(...) is called
}
}
I think the problem is related with:
Core.Kernel implements Core.IKernel. Core.IKernel has AddUserIdentity(...) method.
I'm mocking Core.Kernel instead of mocking a Core.IKernel.
According to Core.IKernel.AddUserIdentity(...) method implementation AddUser should ne reached.
AddUser is an internal virtual method of Core.Kernel. It's not an implementation of any method interface.
I want to assert AddUser is called once when AddUserIdentity is reached.
Other questions about mocking:
For<T> where T is a concrete class -> virtual methods are replaced? no virtual methods are executed?
ForPartsOf<T> where T is a concrete class -> Which parts of this class are mocked (virtual methods, overrided interface methods)?
It is only called once because you are only calling AddUser once. The Received assertion checks how many times it has been called, it doesn't tell NSubstitue to call your method 100 times, you need to do that manually :)
NSubstitute also gives you the option of asserting a specific number of calls were received by passing an integer to Received(). This will throw if the substitute does not receive exactly that many matching calls
http://nsubstitute.github.io/help/received-calls/

Difference Stub Fixture

I am learning codeception and I wonder what is the difference between stubs and fixtures.
Both help me to load well-defined data and kepp tessts simple.
But when do I use
\Codeception\Util\Stub and when do I use
\Codeception\Util\Fixtures
So a stub is what Codeception uses to mock objects. In short, mocking is creating objects that simulate the behaviour of real objects.
Here is an example:
class UpdateBalance
{
public $balanceRepository;
public function __construct(BalanceRepositoryInterface $balanceRepository)
{
$this->balanceRepository = $balanceRepository;
}
public function subtract($amount, $id)
{
$updatedAmount = $this->balanceRepository->subtract($amount, $id);
if ($updatedAmount < 0) {
throw NegativeBalanceException($updatedAmount, $id);
}
return $updatedAmount;
}
}
class UpateBalanceTest extends PHPUnit_Framework_TestCase
{
public function testSubtractThrowsNegativeBalanceException()
{
$balanceRepository = Stub::make(
'BalanceRepositoryInterface'
array(
'subtract' => Stub::atLeastOnce(function() { return -100 })
)
);
$updateBalance = new UpdateBalance($balanceRepository);
$this->expectException(NegativeBalanceException::class);
$updateBalance->subtract(100, 1);
}
}
Note that we don't have a BalanceRepsository class. We have used Codeception stubs and pretended that the BalanceRepository class exists. By pretending it exists we can test the functionality of the UpdateBalance::subtract function by checking that the NegativeBalanceException is thrown.
Fixtures on the other hand would be for sharing test data throughout all your tests. If we use the UpdateBalance::subtract() example again, we could stress test the amount field ensuring it throws the correct exception depending on the amount being passed through:
// In some bootstrap or setup function
Fixtures::add('zero-amount', 0);
Fixtures::add('negative-amount', -1);
Fixtures::add('string-negative-amount', '-1');
class UpdateBalance
{
// ...
public function subtract($amount, $id)
{
if ($amount < 0) {
throw new
}
// ...
}
}
class UpateBalanceTest extends PHPUnit_Framework_TestCase
{
// ...
public function testSubtractThrowsCantSubtractNegativeAmountException()
{
$balanceRepository = Stub::make(
'BalanceRepositoryInterface'
);
$updateBalance = new UpdateBalance($balanceRepository);
$this->expectException(CantSubtractNegativeAmountException::class);
$updateBalance->subtract(Fixture::get('negative-amount'), 1);
}
}
Now we can use our pre-defined fixtures throughout all our tests. I would like to point out that using fixtures in the above example would probably be overkill, but for more complex test data like checking hexadecimal values are valid then it would be a lot more useful.

EasyMock Testing Void With Runnable

I'm trying to test the following class (I've left out the implementation)
public class UTRI implements UTR {
public void runAsUser(String userId, Runnable r);
}
This is the way I would use it:
UTRI.runAsUser("User1", new Runnable () {
private void run() {
//do whatever needs to be done here.
}
});
The problem is, I don't know how to use EasyMock to test functions that return void. That and I'm also not too familiar with testing in general (right out of school!). Can someone help explain to me what I need to do to approach this? I was thinking about making the UTRI a mock and doing expectlastcall after that, but realistically, not sure.
public class UTRITest {
UTRI utri = new UTRI();
#Test
public void testRunAsUser() {
// Create Mocks
Runnable mockRunnable = EasyMock.createMock(Runnable.class);
// Set Expectations
**mockRunnable.run();
EasyMock.expectLastCall().once();**
EasyMock.replay(mockRunnable);
// Call the method under test
utri.runAsUser("RAMBO", **mockRunnable**);
// Verify if run was called on Runnable!!
EasyMock.verify(mockRunnable);
}
}

jmockit - Mocking chain of methods one of which returns a Collection using #Cascading

I am trying to mock a method call which goes something like this:
rapContext.getSysInfo().get(key)
The getSysInfo() method returns a ConcurrentHashMap.
Here is what I have done:
Class ABCTest {
#Cascading RapContext context;
#Test
doTest() {
new Expectations() {
{
rapContext.getSysInfo().get(anyString);
result = new UserPrefCtxObject();
}
}
}
With this I get a NullPointerException on rapContext.getSysInfo(). Call to getSysInfo() returns null. If I call any other method which does not return a collection, for instance rapContext.getDomain() everything working fine.
I am not sure what I am missing.
Thanks
The code example is not complete however you are likely running into some issue associated with accidentally mocking Map. If a Map (or any part of the Collection framework) is mocked then a lot of things will break. I could not reproduce your problem as any attempt to mock RapContext using #Cascading resulted in a stack over flow.
You could partially mock RapContext instead and then either return a real or mocked Map. When I run into similar issues I generally get around them using either #Injectable to only mock an instance of a class or using partial mocks.
Here is an approach that will let you mock getSysInfo:
public class RapContextTest {
#Injectable ConcurrentHashMap<String, Object> mockedMap;
#Test
public void testContext() {
RapContext context = new RapContext();
new MockUp<RapContext>(){
#Mock
public ConcurrentHashMap getSysInfo(){
return mockedMap;
}
};
new NonStrictExpectations() {
{
mockedMap.get(anyString);
result = "Success";
}
};
Object value = context.getSysInfo().get("test");
System.out.println(value);
}
}