Asserting that a method is called exactly one time - tdd

I want to assert that a method is called exactly one time. I'm using RhinoMocks 3.5.
Here's what I thought would work:
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
// the first call I expect the client to use the source
client.GetMeMyThing(key);
// the second call the result should be cached
// and source is not used
client.GetMeMyThing(key);
}
I want this test to fail if the second invocation of GetMeMyThing() calls source.GetSomethingThatTakesALotOfResources().

Here's how I'd verify a method is called once.
[Test]
public void just_once()
{
// Arrange (Important to GenerateMock not GenerateStub)
var a = MockRepository.GenerateMock<ISomeDataSource>();
a.Expect(x => x.GetSomethingThatTakesALotOfResources()).Return(new Something()).Repeat.Once();
// Act
// First invocation should call GetSomethingThatTakesALotOfResources
a.GetMeMyThing();
// Second invocation should return cached result
a.GetMeMyThing();
// Assert
a.VerifyAllExpectations();
}

I have been using the AssertWasCalled extension to get around this problem. This is the best I could find/come up with but it would be better if I didn't have to specify the call twice.
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
// set a positive expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
client.GetMeMyThing(key);
client.GetMeMyThing(key);
source.AssertWasCalled(x => x.GetSomethingThatTakesALotOfResources(key),
x => x.Repeat.Once());
source.VerifyAllExpectations();
}

You may be interested in this bit from the Rhino Mocks 3.5 Documentation (quoted below). Looks like you need to mock the class, not stub it, for it to work the way you expect.
The difference between stubs and mocks
...
A mock is an object that we can set
expectations on, and which will verify
that the expected actions have indeed
occurred. A stub is an object that you
use in order to pass to the code under
test. You can setup expectations on
it, so it would act in certain ways,
but those expectations will never be
verified. A stub's properties will
automatically behave like normal
properties, and you can't set
expectations on them.
If you want to verify the behavior of
the code under test, you will use a
mock with the appropriate expectation,
and verify that. If you want just to
pass a value that may need to act in a
certain way, but isn't the focus of
this test, you will use a stub.
IMPORTANT: A stub will never cause a
test to fail.

Here is what I just did (as recommended by Ray Houston). I would still appreciate a more elegant solution...
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
// set a positive expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
client.GetMeMyThing(key);
// set a negative expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Never();
client.GetMeMyThing(key);
}

You can pass a delegate to WhenCalled to count calls:
...
uint callCount = 0;
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.WhenCalled((y) => { callCount++; });
...
Assert.AreEqual(1, callCount);
Also, you should use a mock not a stub, and verify expectations on the mock too.

You can create strict mock, if you want to ensure that a method is called only once.
var mock = MockRepository.GenerateStrictMock<IMustOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();
var helloWorld= new HelloWorld(mock);
helloworld.Process()
mock.VerifyAllExpectations();

Having a feature called "Exactly" would be handy to write tests on code that might otherwise get into an infinite loop. I would love to write a test such that the second call to a method would raise an exception.
Some libraries for python allow you to sequence expectations, so the first returns false and the second raises an exception.
Rhino won't do that. A partial mock with .Once will intercept the first call, and the rest will be passed on to the original method. So that sucks, but it's true.
You'll have to create a hand-mock. Derive a "testable" class, and give it the ability to raise after the first call.

Related

RxJS BehaviorSubject with custom create logic

Because BehaviorSubject extends Subject and Subject extends Observable, all of those three have static .create(observer) method to create them using custom values emission logic.
I' able to use with good result Observable.create(observer), for instance:
a = Rx.Observable.create(obs => {
setInterval(() => {
obs.next('tick');
}, 500)
})
s = a.subscribe(v => console.log(v))
Gives me expected output (tick every 500ms)
But when I replace Observable with Subject/BehaviorSubject, it's not so willing to get up and running:
a = Rx.Subject.create(obs => {
setInterval(() => {
obs.next('tick');
}, 500)
})
s = a.subscribe(v => console.log(v)); // Nothing
a.next(5); // Still nothing
Basically, subject seems to work as intended to only if they are created via new operator like below:
a = new Rx.Subject();
s = a.subscribe(v => {console.log(v)});
a.next(5) // Ok, got value here
Even if I try to use non-parametrized create method, which invocation shall boil down to same result as using new:
a = Rx.Subject.create();
I'm still unable to force it to emit values.
I'm aware that subjects are designed to receive values from outside world (not to generate them internally as Observables), thus subject shall be triggered by external code with subject.next('value'), but I was just curios that if they are strictly related to Observables, logic behind create and further behavior shall be same...
Can anyone explain, why usage of create on Subject (even if they are not designed to work this way, but still it shall be possible) does not work as supposed to?

Wakanda callMethod synchronous mode

I'm trying to use callMethod() from a method executed on the server.
In this case, I should be able to call it in synchronous mode. However, through trial and error I have found that in this context (i.e. on the server), the method requires three parameters rather than the two mentioned in the docs.
It requires
the first parameter to be a string
the second parameter to be an array
the third parameter to be an object
I've tried quite a few combinations with these parameters but nothing seems to work. At the same time, Wakanda doesn't throw an error as long as the parameters are in the correct form.
Any ideas would be more than welcome.
TIA
Let's suppose we have two variable, one containing the name of the dataClass and the second the name of the dataClass's method :
var myDataClass = "User";
var myMethod = "addUser";
To use the dataClass 'User' and call the method 'addUser' you can do it this way :
var currentClass = ds.dataClasses[myDataClass];
currentClass[myMethod]()
The method callMethod() is a clientSide method, it should be used on prototyper Js files.
try to use it on a button.click event :
button1.click = function button1_click (event)
{
ds.User.callMethod({method:"method1", onSuccess:myFunction, onError:failure});
function myFunction(){
return true;
}
function failure(){
return false;
}
};
To call method in a serverSide js File in a synchronous mode, you can just make the call in this manner :
var test = ds.User.method1();

Single Responsibility Principle, Test Driven Development, and Functional Design

I am fairly new to Test Driven Development and I just started learning the SOLID principles so I was hoping someone could help me out. I'm having some conceptual trouble understanding the Single Responsibility Principle in the context of developing unit tests and methods in the TDD paradigm. For instance, say I want to develop a method that deletes an item from a database- before my code would have looked like the following...
I'd start with defining a test case:
"Delete_Item_ReturnsTrue": function() {
//Setup
var ItemToDelete = "NameOfSomeItem";
//Action
var BooleanResult = Delete( ItemToDelete );
//Assert
if ( BooleanResult === true ) {
return true;
} else {
console.log("Test: Delete_Item_ReturnsTrue() - Failed.");
return false;
}
}
I'd run the test to make sure it failed, then I'd develop the method...
function Delete( ItemToDelete ) {
var Database = ConnectToDatabase();
var Query = BuildQuery( ItemToDelete );
var QueryResult = Database.Query( Query );
if ( QueryResult.error !== true ) {
//if there's no error then...
return true;
} else {
return false;
}
}
If I'm understanding the Single Responsibility Principle correctly, the method that I originally wrote had the responsibilities of deleting the item AND returning true if there wasn't an error. So if I follow the SOLID paradigm the original method should be refactored to look something like...
function Delete( WhatToDelete, WhereToDeleteItFrom ) {
WhereToDeleteItFrom.delete( WhatToDelete );
}
Doing the design as such, changed my method from a boolean function to a void function so now I can't really test the new method in the same manner I was testing my old method.
I guess I could test for thrown exceptions but then doesn't that make it an integration test rather than a unit test because there's no actual exception thrown in the method?
Do I design and implement an extra function which checks the database for use in my unit test?
Do I just not test it because it's void? How exactly does that work in TDD?
Do I pass in a mock repository and then return it after it's state has changed? Doesn't that just essientially bring me back to square one?
Do I pass in a reference to a mock repository and then just test against the repository after the method completes? Wouldn't that be considered a side effect though?
So the single responsibility principle says: They should be exact one reason when I need to change a function.
So let's look at your function:
function Delete( ItemToDelete ) {
var Database = ConnectToDatabase();
var Query = BuildQuery( ItemToDelete );
var QueryResult = Database.Query( Query );
if ( QueryResult.error !== true ) {
//if there's no error then...
return true;
} else {
return false;
}
}
Database changes: ConnectToDatabese() needs a change, but not this function
Changes in the db structure: BuildQuery() needs to be changed (maybe)
...
So on the first look, your function looks good. The naming on some places is a little bit confusing. A function should be start with a small letter. For example "connectToDatabase()". It is a little bit surprising that connectToDatabase returns an Object.
The name BuildQuery seems to be wrong, because BuildQuery( myItem ) returns a query wich is deleting something.
But I would never have such a long complicated function which just one testcase.
You need to write more test cases.
For the first test case you could write the function like that:
function Delete( ItemToDelete) {
return true
}
The next testcase could be "call the buildDeleteQuery function with the item id". At that point you need to think about how you call your db. If you have a dbObject, which does that you could mock that Object.
function Delete( ItemToDelete ) {
buildDeleteQuery( ItemToDelete.id )
return true
}
Now more and more test cases. Remember that there will be also test cases for buildDeleteQuery. But for the outer function you could mock buildDeleteQuery.
Now to answer some of your questions:
When you first write the test and then write the code, you will have testable code.
That code looks different, because the tests should be not to complicated. When you want easy tests you will automaticly have more smaller functions.
Yes, you will write a test for every function you call.
Maybe you will mock objects. And if you are not able to test your db call without a wrapping function you will create a function, which allows you to test that functionality.
Remember your tests are the documentation of your code. So keep them simple as possible.
But the most important thing: Keep practicing! When you start with TDD it takes some time. A good and fun resource is: Uncle Bobs Bowling Kata Just download the slides from the website and look how tdd is done step by step.

Can you record accessed methods in Visual Studio?

I'm retroactively documenting and writing unit tests for some C# code. I would like to determine what code is actually being used and when.
In Visual Studio 2012, is there a way to record all the methods accessed and in what order while walking through specific scenarios?
You could run your application with a profiler attached, which will give you all accessed methods, call chains, counts, etc.
The Visual Studio Profiler will give you the time spent in each method, and let you inspect the call heirarchy. I don't know if it will give you the exact order they were called in though.
EDIT: Apparently attaching the profiler to a running unit test is harder in VS2012.
Are you wanting to execute a test method that make sure that a particular method on a class was invoked ? If so i dont know of a way to do it in VS alone, but you can use a mock framework to create dependency mocks and check values on them. Here is a snippet of a unit test:
[TestMethod]
public void HttpPostPrivacyPolicyFacadeSvcErrorTest()
{
var controller = ControllerHelper.GetRouteController();
controller.Session[SessionVariable.User] = new UserInfo() { UserName = Config.Data.Username };
var idmSvcMock = new Mock<IUserServiceDAO>();
var facadeSvcMock = new Mock<IFacadeSvcDAO>();
//setup the facade mock to throw exception to simulate FacadeServiceException
facadeSvcMock.Setup(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>())).Throws<Exception>();
var userCollectorMock = new Mock<IUserInfoCollector>();
userCollectorMock.Setup(x => x.GetUserInfo()).Returns(new UserInfo() { UserName = Config.Data.Username });
controller.FacadeSvc = facadeSvcMock.Object;
controller.UserServiceDAO = idmSvcMock.Object;
controller.UserCollector = userCollectorMock.Object;
controller.DefaultErrorId = "Route_errors_Unabletoprocess";
//action
var res = controller.Privacy(new FormCollection());
//assert
//make sure we go to the right controller, action, with the correct params.
res.AssertActionRedirect().ToController("Errors").ToAction("Index").WithParameter("id", "Route_errors_Unabletoprocess");
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>()), Times.Exactly(1));
In the test above i check that SetPrivacyAcceptance was invoked once and only once on my facadeSvcMock instance. More on moq here: Moq
this block of code is actually checking how many times SetPrivacyAcceptanceStatus was invoked:
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny()), Times.Exactly(1));
the It.IsAny() is the one parameter to that method, so the line above says basically "For any input parameter of type UserInfo verify that we invoked SetPrivacyAcceptanceStatus exactly once."

using Moq - void return type method Unit test

I am writing unittest for void method actually that method load the collection in
ViewData["CityList"] method is
public void PopulateCityCombo() {
IEnumerable<Cities> c= service.GetCities();
ViewData["CityList"] = c.Select(e => new Cities{ ID = e.ID, Name = e.Name});
}
now i do not know how to unit test using Moq since controller method is void and not returning data, can any one tell i will achive that.
On a side note, I would shy away from using ViewData within controller methods as per your example. The ViewData dictionary approach is fast and fairly easy to implement, however it can lead to typo's and errors that are not caught at compile time. An alternative would be to use the ViewModel pattern which allows you to use strongly-typed classes for the specific view you need to expose values or content within. Ultimately giving you type safe and compile time checking along with intellisense.
Switching to the ViewModel pattern would allow you to call the PopulateCityCombo() method from your controller to populate a ViewModel that in turn would passed to the corresponding view.
From there you would need to inject a mock service layer into your controllers constructor from your unit test.
// arrange
var mock = new Mock<servicelayer>();
mock.Setup(x=>x.GetCities()).Returns(expectedData);
var controller = new YourController(mock.Object);
// act
var result = controller.ControllerMethod() as ViewResult;
var resultData = (YourViewModel)result.ViewData.Model;
// assert
// Your assertions

Resources