dionisiydk / mocketry Goto Github PK
View Code? Open in Web Editor NEWMock objects framework
License: MIT License
Mock objects framework
License: MIT License
Just tried the following example from the docs and it seems to always pass?
| mock flag |
mock := Mock new.
mock someMessage
when: [flag] is: true.
flag := false.
mock someMessage. "will fail immediately on call by last condition: flag should be true"
mock := Mock new.
mock stub anyMessage willreturn:: 100. "<== willreturn:: rather than willReturn:"
mock someMessage should be: 100.
mock someMessage2 should be: 100.
There are few issues causing Mocketry not working properly on Pharo 9.
MockCleaningProcessHook
is required to have some more methods - isSuspended
, isTerminated
and priority
.
TestExecutionEnvironment
extension createMockBehaviour
uses variable forkedProcesses that does not exist anymore.
(mock messageWith: 'test' should be: #anyString
rather than
(mock messageWith: 'test') should be: #anyString
It is easy to forget to put #stub message when defining expected behavior:
mock someMessage willReturn: #result
It does not fail right now because of automock behavior:
So it does not fail while expectation is not defined. And test is that case can simply pass the default scenario (without simulated condition).
Here this behavior needs to be improved. "Mock expectation" protocol should fail when it is not under learning mode.
Mocketry does not pass Pharo release categorization tests
I wanted to load the 'Core' group of Mocketry to limit the amount of code I load in some project but doing so still loads the tests of StateSpecs and Ghost.
Maybe the granularity of the groups could be reworked so that we can avoid to load the tests of the dependencies when we do not load the tests of Mocketry?
Hi Denis! @dionisiydk
As part of my activities on Exercism project, where your Mocketry library is used, I have some question around running code with mock instances:
I want to have following statement (simplified):
testExecuteDownloading
| cmd exercise mockHttpClient mockReader baseUrl |
Any strictMocks: false.
mockHttpClient := ExercismHttpClient asMock.
mockReader := TonelReader asMock.
[
cmd := (ExercismDownloadCommand
from: mockHttpClient track: 'pharo' exercise: 'test-exercise')
yourself.
exercise := cmd execute. "tonel reader used in this code"
self assert: exercise notNil description: 'Get a result'.
sourceCode := exercise contentsFor: 'test1.st' ifAbsent: [''].
self assert: sourceCode equals: 'Some source1'
] runWithMockSetup: [
mockHttpClient expect verifyToken atLeastOnce.
"... + some other stub sessages for mockClient"
(mockReader expect loadDefinitions) willReturnYourself.
].
Code above is kind-of integration test, that execution is done properly (I have some more dedicated unit tests on objects/classes used in command execution).
Problem is that I don't know how to stub just certain instance side method of TonelReader that is used in code of execution of command above. TonelReader is instantiated as one of local variables of method executed on other object of download command (so it is internal implementation that shouldn't be really exposed as part of command interface).
Should I just stub constructor method (class side) of TonelReader class that would return an instance of TonelReader mock (with dedicated stub instance side method)?
Thanks much for your answer!
David
I'm trying to launch tests using Mocks from Mocketry in Pharo 9 but I get errors.
One of my test:
testRecord
| stream |
stream := '' writeStream.
[ Stdio stub stdout willReturn: stream.
logger record: 'This is a test'.
self assert: (stream contents asString lines last includesSubstring: 'This is a test') ]
ensure: [ Stdio recoverFromGHMutation.
stream close ]
The stack:
UndefinedObject>>doesNotUnderstand: #add:
TestExecutionEnvironment>>createMockBehaviour
MockCurrentBehaviour>>value
MockCurrentBehaviour class(ProcessSpecificVariable class)>>value
Stdio class(Object)>>stub
[ Stdio stub stdout willReturn: stream.
logger record: 'This is a test'.
self assert: (stream contents asString lines last includesSubstring: 'This is a test') ] in TinyStdoutLoggerTest>>testRecord in Block: [ Stdio stub stdout willReturn: stream....
FullBlockClosure(BlockClosure)>>ensure:
TinyStdoutLoggerTest>>testRecord
TinyStdoutLoggerTest(TestCase)>>performTest
[self setUp.
self performTest] in TinyStdoutLoggerTest(TestCase)>>runCase in Block: [self setUp....
FullBlockClosure(BlockClosure)>>ensure:
TinyStdoutLoggerTest(TestCase)>>runCase
[aTestCase runCase] in [
[aTestCase runCase] ensure: [
"Terminated test is not considered as completed (user just closed a debugger for example)"
mainTestProcess isTerminating ifFalse: [
self handleCompletedTest ]]
] in TestExecutionEnvironment>>runTestCaseUnderWatchdog: in Block: [aTestCase runCase]
FullBlockClosure(BlockClosure)>>ensure:
[
[aTestCase runCase] ensure: [
"Terminated test is not considered as completed (user just closed a debugger for example)"
mainTestProcess isTerminating ifFalse: [
self handleCompletedTest ]]
] in TestExecutionEnvironment>>runTestCaseUnderWatchdog: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
TestExecutionEnvironment>>runTestCaseUnderWatchdog:
[self runTestCaseUnderWatchdog: aTestCase] in TestExecutionEnvironment>>runTestCase: in Block: [self runTestCaseUnderWatchdog: aTestCase]
FullBlockClosure(BlockClosure)>>ensure:
TestExecutionEnvironment>>runTestCase:
[
testEnv runTestCase: aTestCase] in DefaultExecutionEnvironment>>runTestCase: in Block: [...
[ self value: anExecutionEnvironment.
anExecutionEnvironment activated.
aBlock value ] in CurrentExecutionEnvironment class>>activate:for: in Block: [ self value: anExecutionEnvironment....
FullBlockClosure(BlockClosure)>>ensure:
CurrentExecutionEnvironment class>>activate:for:
TestExecutionEnvironment(ExecutionEnvironment)>>beActiveDuring:
DefaultExecutionEnvironment>>runTestCase:
CurrentExecutionEnvironment class>>runTestCase:
TinyStdoutLoggerTest(TestCase)>>runCaseManaged
[
aTestCase announce: TestCaseStarted withResult: self.
aTestCase runCaseManaged.
aTestCase announce: TestCaseEnded withResult: self.
"To not affect performance of big test suites following logic is not inside addPass: method"
errors remove: aTestCase ifAbsent: [].
failures remove: aTestCase ifAbsent: [].
self addPass: aTestCase] in TestResult>>runCaseForDebug: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
I've tried to define dependency for P11, P12 using:
spec
baseline: 'Mocketry'
with: [ spec repository: 'github://dionisiydk/Mocketry:v7.0.x' ].
See: https://github.com/exercism/pharo-smalltalk/actions/runs/7871570770/job/21475121571#step:4:100
Also tried to load manually:
Metacello new
baseline: 'Mocketry';
repository: 'github://dionisiydk/Mocketry:v7.0.x';
load
But I have "Revspec v7.0.x not found" error. Am I doing something wrong here?
The following test shows the issue:
MockAcceptanceTests>>testUnexpectedMessageDefinedInObjectUsingAnotherObjectMethod
| actual |
actual := mock printString.
actual should be: 'a GHEmptyMetaMessages'
The unexpected message leads to #stubDoesNotExpect: hook which is trying to use Object real methods as default action to handle the message. It does not work well for Object methods with self sends.
Possible improvement would be to use standard meta level for meta messages sent under deep meta call (which is happens in the example).
On the new 10th version of Pharo Mocketry fails while creating a new Mock stub or stub:
OrderedCollection(Object)>>errorSubscriptBounds:
OrderedCollection>>at:
SpNotebookPresenter>>selectPageIndex:
StObjectInspectorPresenter>>updatePages
StObjectInspectorPresenter>>refresh
StObjectInspectorPresenter>>initializePresenters
StObjectInspectorPresenter(SpPresenter)>>initializePrivateHooks
StObjectInspectorPresenter(SpPresenter)>>initialize
StObjectInspectorPresenter>>initialize
StObjectInspectorPresenter class(SpPresenter class)>>newApplication:owner:model:
StObjectInspectorPresenter class(StPresenter class)>>owner:on:
StInspector(SpPresenter)>>instantiate:on:
StInspector>>newInspectorFor:
[ :aModel | self newInspectorFor: aModel ] in StInspector>>initializePresenters in Block: [ :aModel | self newInspectorFor: aModel ]
SpMillerColumnPresenter>>newPresenterFor:
SpMillerColumnPresenter>>pushModel:
SpMillerColumnPresenter>>setRootModel:
StInspector>>initializePresenters
StInspector(SpPresenter)>>initializePrivateHooks
StInspector(SpPresenter)>>initialize
StInspector class(SpPresenter class)>>newApplication:model:
StInspector class(SpPresenter class)>>on:
StInspector class>>onObject:
StInspector class>>openOn:
SpCodeInspectItCommand>>inspectObject:
[ :result |
self inspectObject: result ] in SpCodeInspectItCommand>>execute in Block: [ :result | ...
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluate:andDo:
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluateSelectionAndDo:
SpCodeInspectItCommand>>execute
SpCommand(CmCommandDecorator)>>execute
GHMetaMessages class(ProtoObject)>>primitiveFailed:
GHMetaMessages class(ProtoObject)>>primitiveFailed
GHMetaMessages class>>setClass:to:
ByteString(ProtoObject)>>injectGHMutation:
ByteString class(GHObjectMutation)>>mutate:
ByteString(Object)>>stub
UndefinedObject>>DoIt
[ receiver withArgs: (context ifNil: [ #() ] ifNotNil: [ {context} ]) executeMethod: self compileDoit] in OpalCompiler>>evaluate in Block: [ receiver withArgs: (context ifNil: [ #() ] ifNot...etc...
FullBlockClosure(BlockClosure)>>on:do:
OpalCompiler>>evaluate
[
oldBindings := self interactionModel bindings copy.
receiver := self interactionModel doItReceiver.
result := receiver class compiler
source: aString readStream;
context: self interactionModel doItContext;
receiver: self interactionModel doItReceiver;
requestor: self interactionModel;
environment: self environment;
failBlock: [ ^ compileErrorBlock value ];
evaluate.
oldBindings size = self interactionModel bindings size
ifFalse: [ self withAdapterDo: [ :anAdapter | anAdapter refreshStyling ] ].
result ] in SpCodePresenter>>evaluate:onCompileError:onError: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
SpCodePresenter>>evaluate:onCompileError:onError:
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluate:andDo:
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluateSelectionAndDo:
SpCodeInspectItCommand>>execute
SpCommand(CmCommandDecorator)>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
psValueAt: index
put: anObject.
aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[
aCmCommand canBeExecuted
ifTrue: [ aCmCommand execute ] ] in SpKMCategoryBuilder>>visitCommand: in Block: [ ...
Our Exercism project is referencing this githhub repo of Mocketry.
When loading I get a filename or extension is too long error
with Windows Pharo 7.0.3, exercism/pharo-smalltalk#328
Can this repo be converted to Tonel?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.