Documentation for release 3.1 (2011-11-10)
© 2001-2011 OFFIS, Tammo Freese, Henri Tremblay.
EasyMock is a library that provides an easy way to use Mock Objects for given interfaces or classes. EasyMock is available under the terms of the Apache 2 license.
Mock Objects simulate parts of the behavior of domain code, and are able to check whether they are used as defined. Domain classes can be tested in isolation by simulating their collaborators with Mock Objects.
Writing and maintaining Mock Objects often is a tedious task that may introduce errors. EasyMock generates Mock Objects dynamically - no need to write them, and no generated code!
<dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.1</version> <scope>test</scope> </dependency>You can obviously use any other dependency tool compatible with the Maven repository.
easymock-3.1.zip
).easymock-3.1
directory.easymock.jar
) to your classpath.easymock-3.1-tests.jar
and can be launched with a JUnit TestRunner
having JUnit 4.7 on top of EasyMock, cglib and Objenesis in your classpath.easymock-3.1-sources.jar
.Most parts of a software system do not work in isolation, but collaborate with other parts to get their job done. In a lot of cases, we do not care about using collaborators in unit testing, as we trust these collaborators. If we do care about it, Mock Objects help us to test the unit under test in isolation. Mock Objects replace collaborators of the unit under test.
The following examples use the interface Collaborator
:
package org.easymock.samples; public interface Collaborator { void documentAdded(String title); void documentChanged(String title); void documentRemoved(String title); byte voteForRemoval(String title); byte[] voteForRemovals(String[] title); }
Implementors of this interface are collaborators
(in this case listeners) of a class named ClassUnderTest
:
public class ClassUnderTest { // ... public void addListener(Collaborator listener) { // ... } public void addDocument(String title, byte[] document) { // ... } public boolean removeDocument(String title) { // ... } public boolean removeDocuments(String[] titles) { // ... } }
The code for both the class and the interface may be found
in the package org.easymock.samples
in easymock-3.1-samples.jar
from the EasyMock zip delivery.
The following examples assume that you are familiar with the JUnit testing framework. Although the tests shown here use JUnit 4, you may as well use JUnit 3 or TestNG.
We will now build a test case and toy around with it to understand the
functionality of the EasyMock package. easymock-3.1-samples.jar
contains a modified version of this test. Our first test should check
whether the removal of a non-existing document does not lead to a notification
of the collaborator. Here is the test without the definition of the
Mock Object:
package org.easymock.samples; import org.junit.*; public class ExampleTest { private ClassUnderTest classUnderTest; private Collaborator mock; @Before public void setUp() { classUnderTest = new ClassUnderTest(); classUnderTest.addListener(mock); } @Test public void testRemoveNonExistingDocument() { // This call should not lead to any notification // of the Mock Object: classUnderTest.removeDocument("Does not exist"); } }
For many tests using EasyMock,
we only need a static import of methods of org.easymock.EasyMock
.
import static org.easymock.EasyMock.*; import org.junit.*; public class ExampleTest { private ClassUnderTest classUnderTest; private Collaborator mock; }
To get a Mock Object, we need to
Here is a first example:
@Before public void setUp() { mock = createMock(Collaborator.class); // 1 classUnderTest = new ClassUnderTest(); classUnderTest.addListener(mock); } @Test public void testRemoveNonExistingDocument() { // 2 (we do not expect anything) replay(mock); // 3 classUnderTest.removeDocument("Does not exist"); }
After activation in step 3, mock
is a Mock Object for the Collaborator
interface that expects no calls. This means that if we change
our ClassUnderTest
to call
any of the interface's methods, the Mock Object will throw
an AssertionError
:
java.lang.AssertionError: Unexpected method call documentRemoved("Does not exist"): at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) at $Proxy0.documentRemoved(Unknown Source) at org.easymock.samples.ClassUnderTest.notifyListenersDocumentRemoved(ClassUnderTest.java:74) at org.easymock.samples.ClassUnderTest.removeDocument(ClassUnderTest.java:33) at org.easymock.samples.ExampleTest.testRemoveNonExistingDocument(ExampleTest.java:24) ...
Let us write a second test. If a document
is added on the class under test, we expect a call to mock.documentAdded()
on the Mock Object with the title of the document as argument:
@Test public void testAddDocument() { mock.documentAdded("New Document"); // 2 replay(mock); // 3 classUnderTest.addDocument("New Document", new byte[0]); }
So in the record state (before calling replay
),
the Mock Object does not behave like a Mock Object,
but it records method calls. After calling replay
,
it behaves like a Mock Object, checking whether the expected
method calls are really done.
If classUnderTest.addDocument("New Document", new byte[0])
calls the expected method with a wrong argument, the Mock Object will complain
with an AssertionError
:
java.lang.AssertionError: Unexpected method call documentAdded("Wrong title"): documentAdded("New Document"): expected: 1, actual: 0 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) at $Proxy0.documentAdded(Unknown Source) at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:61) at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:28) at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) ...
All missed expectations are shown, as well as all fulfilled expectations for the unexpected call (none in this case). If the method call is executed too often, the Mock Object complains, too:
java.lang.AssertionError: Unexpected method call documentAdded("New Document"): documentAdded("New Document"): expected: 1, actual: 2 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) at $Proxy0.documentAdded(Unknown Source) at org.easymock.samples.ClassUnderTest.notifyListenersDocumentAdded(ClassUnderTest.java:62) at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:29) at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:30) ...
There is one error that we have not handled so far: If we specify
behavior, we would like to verify that it is actually used. The current
test would pass if no method on the Mock Object is called. To verify that the
specified behavior has been used, we have to call
verify(mock)
:
@Test public void testAddDocument() { mock.documentAdded("New Document"); // 2 replay(mock); // 3 classUnderTest.addDocument("New Document", new byte[0]); verify(mock); }
If the method is not called on the Mock Object, we now get the following exception:
java.lang.AssertionError: Expectation failure on verify: documentAdded("New Document"): expected: 1, actual: 0 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) at org.easymock.EasyMock.verify(EasyMock.java:536) at org.easymock.samples.ExampleTest.testAddDocument(ExampleTest.java:31) ...
The message of the exception lists all missed expectations.
Up to now, our test has only considered a single method call. The next
test should check whether the addition of an already existing
document leads to a call to mock.documentChanged()
with the appropriate argument. To be sure, we check this three
times (hey, it is an example ;-)):
@Test public void testAddAndChangeDocument() { mock.documentAdded("Document"); mock.documentChanged("Document"); mock.documentChanged("Document"); mock.documentChanged("Document"); replay(mock); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); verify(mock); }
To avoid the repetition of mock.documentChanged("Document")
,
EasyMock provides a shortcut. We may specify the call count with the method
times(int times)
on the object returned by
expectLastCall()
. The code then looks like:
@Test public void testAddAndChangeDocument() { mock.documentAdded("Document"); mock.documentChanged("Document"); expectLastCall().times(3); replay(mock); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); classUnderTest.addDocument("Document", new byte[0]); verify(mock); }
If the method is called too often, we get an exception that tells us that the method has been called too many times. The failure occurs immediately at the first method call exceeding the limit:
java.lang.AssertionError: Unexpected method call documentChanged("Document"): documentChanged("Document"): expected: 3, actual: 4 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) at $Proxy0.documentChanged(Unknown Source) at org.easymock.samples.ClassUnderTest.notifyListenersDocumentChanged(ClassUnderTest.java:67) at org.easymock.samples.ClassUnderTest.addDocument(ClassUnderTest.java:26) at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) ...
If there are too few calls, verify(mock)
throws an AssertionError
:
java.lang.AssertionError: Expectation failure on verify: documentChanged("Document"): expected: 3, actual: 2 at org.easymock.internal.MocksControl.verify(MocksControl.java:70) at org.easymock.EasyMock.verify(EasyMock.java:536) at org.easymock.samples.ExampleTest.testAddAndChangeDocument(ExampleTest.java:43) ...
For specifying return values,
we wrap the expected call in expect(T value)
and specify the return value
with the method andReturn(Object returnValue)
on the object returned by
expect(T value)
.
As an example, we check the workflow for document
removal. If ClassUnderTest
gets a call for document
removal, it asks all collaborators for their vote for removal
with calls to byte voteForRemoval(String title)
value.
Positive return values are a vote for
removal. If the sum of all values is positive, the document is removed
and documentRemoved(String title)
is called on
all collaborators:
@Test public void testVoteForRemoval() { mock.documentAdded("Document"); // expect document addition // expect to be asked to vote for document removal, and vote for it expect(mock.voteForRemoval("Document")).andReturn((byte) 42); mock.documentRemoved("Document"); // expect document removal replay(mock); classUnderTest.addDocument("Document", new byte[0]); assertTrue(classUnderTest.removeDocument("Document")); verify(mock); } @Test public void testVoteAgainstRemoval() { mock.documentAdded("Document"); // expect document addition // expect to be asked to vote for document removal, and vote against it expect(mock.voteForRemoval("Document")).andReturn((byte) -42); replay(mock); classUnderTest.addDocument("Document", new byte[0]); assertFalse(classUnderTest.removeDocument("Document")); verify(mock); }
The type of the returned value is checked at compile time. As an example, the following code will not compile, as the type of the provided return value does not match the method's return value:
expect(mock.voteForRemoval("Document")).andReturn("wrong type");
Instead of calling expect(T value)
to retrieve the object for setting the return value,
we may also use the object returned by expectLastCall()
.
Instead of
expect(mock.voteForRemoval("Document")).andReturn((byte) 42);
we may use
mock.voteForRemoval("Document"); expectLastCall().andReturn((byte) 42);
This type of specification should only be used if the line gets too long, as it does not support type checking at compile time.
For specifying exceptions (more exactly: Throwables) to be thrown, the object returned by
expectLastCall()
and expect(T value)
provides the method
andThrow(Throwable throwable)
.
The method has to be called in record state after the call to the Mock Object for
which it specifies the Throwable
to be thrown.
Unchecked exceptions (that is, RuntimeException
, Error
and all their subclasses) can be thrown from every method. Checked exceptions can only be
thrown from the methods that do actually throw them.
Sometimes we would like our mock object to return a value or throw an exception
that is created at the time of the actual call. Since EasyMock 2.2, the object returned by
expectLastCall()
and expect(T value)
provides the method
andAnswer(IAnswer answer)
which allows to specify an implementation of the
interface IAnswer
that is used to create the return value or exception.
Inside an IAnswer
callback, the arguments passed to the mock call
are available via EasyMock.getCurrentArguments()
.
If you use these, refactorings like reordering parameters may break your tests.
You have been warned.
An alternative to IAnswer
are the andDelegateTo
and
andStubDelegateTo
methods. They allow to delegate the call to a
concrete implementation of the mocked interface that will then provide the answer.
The pros are that the arguments found in EasyMock.getCurrentArguments()
for IAnswer
are now passed to the method of the concrete implementation.
This is refactoring safe. The cons are that you have to provide an implementation
which is kind of doing a mock manually... Which is what you try to avoid by
using EasyMock. It can also be painful if the interface has many methods. Finally,
the type of the concrete class can't be checked statically against the mock type.
If for some reason, the concrete class isn't implementing the method that is
delegated, you will get an exception during the replay only. However, this
case should be quite rare.
To understand correctly the two options, here is an example:
List<String> l = createMock(List.class); // andAnswer style expect(l.remove(10)).andAnswer(new IAnswer<String>() { public String answer() throws Throwable { return getCurrentArguments()[0].toString(); } }); // andDelegateTo style expect(l.remove(10)).andDelegateTo(new ArrayList<String>() { @Override public String remove(int index) { return Integer.toString(index); } });
It is also possible to specify a changing behavior for a method.
The methods times
, andReturn
, and andThrow
may be chained. As an example, we define voteForRemoval("Document")
to
RuntimeException
for the next four calls,
expect(mock.voteForRemoval("Document")) .andReturn((byte) 42).times(3) .andThrow(new RuntimeException(), 4) .andReturn((byte) -42);
To relax the expected call counts, there are additional methods
that may be used instead of times(int count)
:
times(int min, int max)
min
and max
calls,atLeastOnce()
anyTimes()
If no call count is specified, one call is expected. If we would like to state this
explicitely, once()
or times(1)
may be used.
On a Mock Object returned by a EasyMock.createMock()
,
the order of method calls is not checked.
If you would like a strict Mock Object that checks the order of method calls,
use EasyMock.createStrictMock()
to create it.
If an unexpected method is called on a strict Mock Object,
the message of the exception will show the method calls
expected at this point followed by the first conflicting one.
verify(mock)
shows all missing method calls.
Sometimes, it is necessary to have a Mock Object that checks the order of only some calls.
In record phase, you may switch order checking on by calling checkOrder(mock, true)
and switch it off by calling checkOrder(mock, false)
.
There are two differences between a strict Mock Object and a normal Mock Object:
To match an actual method call on the Mock Object with an
expectation, Object
arguments are by default compared with
equals()
. This may lead to problems. As an example,
we consider the following expectation:
String[] documents = new String[] { "Document 1", "Document 2" }; expect(mock.voteForRemovals(documents)).andReturn(42);
If the method is called with another array with the same contents,
we get an exception, as equals()
compares object
identity for arrays:
java.lang.AssertionError: Unexpected method call voteForRemovals([Ljava.lang.String;@9a029e): voteForRemovals([Ljava.lang.String;@2db19d): expected: 1, actual: 0 documentRemoved("Document 1"): expected: 1, actual: 0 documentRemoved("Document 2"): expected: 1, actual: 0 at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29) at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:44) at $Proxy0.voteForRemovals(Unknown Source) at org.easymock.samples.ClassUnderTest.listenersAllowRemovals(ClassUnderTest.java:88) at org.easymock.samples.ClassUnderTest.removeDocuments(ClassUnderTest.java:48) at org.easymock.samples.ExampleTest.testVoteForRemovals(ExampleTest.java:83) ...
To specify that only array equality is needed for this call, we may use the method
aryEq
that is statically imported from the EasyMock
class:
String[] documents = new String[] { "Document 1", "Document 2" }; expect(mock.voteForRemovals(aryEq(documents))).andReturn(42);
If you would like to use matchers in a call, you have to specify matchers for all arguments of the method call.
There are a couple of predefined argument matchers available.
eq(X value)
anyBoolean()
, anyByte()
, anyChar()
, anyDouble()
, anyFloat()
, anyInt()
, anyLong()
, anyObject()
, anyObject(Class clazz)
, anyShort()
eq(X value, X delta)
float
and double
.aryEq(X value)
Arrays.equals()
. Available for primitive and object arrays.isNull()
, isNull(Class clazz)
notNull()
, notNull(Class clazz)
same(X value)
isA(Class clazz)
lt(X value)
, leq(X value)
, geq(X value)
, gt(X value)
Comparable
.startsWith(String prefix), contains(String substring), endsWith(String suffix)
String
s.matches(String regex), find(String regex)
String
s.and(X first, X second)
first
and second
both match. Available for all primitive types and for objects.or(X first, X second)
first
and second
match. Available for all primitive types and for objects.not(X value)
value
does not match.cmpEq(X value)
Comparable.compareTo(X o)
. Available for all numeric primitive types and Comparable
.cmp(X value, Comparator<X> comparator, LogicalOperator operator)
comparator.compare(actual, value) operator 0
where the operator is <,<=,>,>= or ==. Available for objects.capture(Capture<T> capture)
, captureXXX(Capture<T> capture)
Capture
parameter for later access. You can do and(someMatcher(...), capture(c))
to
capture a parameter from a specific call to the method. You can also specify a CaptureType
telling that a given Capture
should keep
the first, the last, all or no captured values.Sometimes it is desirable to define own argument matchers. Let's say that an argument matcher is needed that matches an exception if the given exception has the same type and an equal message. It should be used this way:
IllegalStateException e = new IllegalStateException("Operation not allowed.") expect(mock.logThrowable(eqException(e))).andReturn(true);
Two steps are necessary to achieve this: The new argument matcher has to be defined,
and the static method eqException
has to be declared.
To define the new argument matcher, we implement the interface org.easymock.IArgumentMatcher
.
This interface contains two methods: matches(Object actual)
checks whether the actual argument
matches the given argument, and appendTo(StringBuffer buffer)
appends a string representation
of the argument matcher to the given string buffer. The implementation is straightforward:
import org.easymock.IArgumentMatcher; public class ThrowableEquals implements IArgumentMatcher { private Throwable expected; public ThrowableEquals(Throwable expected) { this.expected = expected; } public boolean matches(Object actual) { if (!(actual instanceof Throwable)) { return false; } String actualMessage = ((Throwable) actual).getMessage(); return expected.getClass().equals(actual.getClass()) && expected.getMessage().equals(actualMessage); } public void appendTo(StringBuffer buffer) { buffer.append("eqException("); buffer.append(expected.getClass().getName()); buffer.append(" with message \""); buffer.append(expected.getMessage()); buffer.append("\"")"); } }
The method eqException
must create the argument matcher with the given Throwable,
report it to EasyMock via the static method reportMatcher(IArgumentMatcher matcher)
,
and return a value so that it may be used inside the call
(typically 0
, null
or false
). A first attempt may look like:
public static Throwable eqException(Throwable in) { EasyMock.reportMatcher(new ThrowableEquals(in)); return null; }
However, this only works if the method logThrowable
in the example usage accepts
Throwable
s, and does not require something more specific like a RuntimeException
.
In the latter case, our code sample would not compile:
IllegalStateException e = new IllegalStateException("Operation not allowed.") expect(mock.logThrowable(eqException(e))).andReturn(true);
Java 5.0 to the rescue: Instead of defining eqException
with a Throwable
as
parameter and return value, we use a generic type that extends Throwable
:
public static <T extends Throwable> T eqException(T in) { reportMatcher(new ThrowableEquals(in)); return null; }
Mock Objects may be reset by reset(mock)
.
If needed, a mock can also be converted from one type to another by calling resetToNice(mock)
,
resetToDefault(mock)
ou resetToStrict(mock)
.
Sometimes, we would like our Mock Object to respond to some method calls, but we do not want to
check how often they are called, when they are called, or even if they are called at all.
This stub behavoir may be defined by using the methods andStubReturn(Object value)
,
andStubThrow(Throwable throwable)
, andStubAnswer(IAnswer<Tgt; answer)
and asStub()
. The following code
configures the MockObject to answer 42 to voteForRemoval("Document")
once
and -1 for all other arguments:
expect(mock.voteForRemoval("Document")).andReturn(42); expect(mock.voteForRemoval(not(eq("Document")))).andStubReturn(-1);
On a Mock Object returned by createMock()
the default behavior for all methods is to throw an
AssertionError
for all unexpected method calls.
If you would like a "nice" Mock Object that by default allows all method calls and returns
appropriate empty values (0
, null
or false
), use createNiceMock()
instead.
The behavior for the four Object methods equals()
,
hashCode()
, toString()
and finalize()
cannot be changed for Mock Objects created with EasyMock,
even if they are part of the interface for which the
Mock Object is created.
Up to this point, we have seen a mock object as a single object that is configured by static methods
on the class EasyMock
. But many of these static methods just identify the hidden control of the Mock Object
and delegate to it. A Mock Control is an object implementing the IMocksControl
interface.
So instead of
IMyInterface mock = createStrictMock(IMyInterface.class); replay(mock); verify(mock); reset(mock);
we may use the equivalent code:
IMocksControl ctrl = createStrictControl(); IMyInterface mock = ctrl.createMock(IMyInterface.class); ctrl.replay(); ctrl.verify(); ctrl.reset();
The IMocksControl allows to create more than one Mock Object, and so it is possible to check the order of method calls
between mocks. As an example, we set up two mock objects for the interface IMyInterface
, and we expect the calls
mock1.a()
and mock2.a()
ordered, then an open number of calls to mock1.c()
and mock2.c()
, and finally mock2.b()
and mock1.b()
, in this order:
IMocksControl ctrl = createStrictControl(); IMyInterface mock1 = ctrl.createMock(IMyInterface.class); IMyInterface mock2 = ctrl.createMock(IMyInterface.class); mock1.a(); mock2.a(); ctrl.checkOrder(false); mock1.c(); expectLastCall().anyTimes(); mock2.c(); expectLastCall().anyTimes(); ctrl.checkOrder(true); mock2.b(); mock1.b(); ctrl.replay();
Mock Objects can be named at creation using
createMock(String name, Class<T> toMock)
,
createStrictMock(String name, Class<T> toMock)
or
createNiceMock(String name, Class<T> toMock)
.
The names will be shown in exception failures.
Mocks can be serialized at any time during their life. However, there are some obvious contraints:
During recording, a mock is not thread-safe. So a giving mock (or mocks linked to the same IMocksControl
)
can only be recorded from a single thread. However, different mocks can be recorded simultaneously in different threads.
During the replay phase, mocks are by default thread-safe. This can be change for a given mock if makeThreadSafe(mock, false)
is called during the recording phase. This can prevent deadlocks in some rare situations.
Finally, calling checkIsUsedInOneThread(mock, true)
on a mock will make sure the mock is used in only one thread and
throw an exception otherwise. This can be handy to make sure a thread-unsafe mocked object is used correctly.
EasyMockSupport
is a class that meant to be used as a helper or base class to your test cases. It will automatically registers all
created mocks (or in fact all created controls) and to replay, reset or verify them in batch instead of explicitly. Here's a JUnit example:
public class SupportTest extends EasyMockSupport { private Collaborator firstCollaborator; private Collaborator secondCollaborator; private ClassTested classUnderTest; @Before public void setup() { classUnderTest = new ClassTested(); } @Test public void addDocument() { // creation phase firstCollaborator = createMock(Collaborator.class); secondCollaborator = createMock(Collaborator.class); classUnderTest.addListener(firstCollaborator); classUnderTest.addListener(secondCollaborator); // recording phase firstCollaborator.documentAdded("New Document"); secondCollaborator.documentAdded("New Document"); replayAll(); // replay all mocks at once // test classUnderTest.addDocument("New Document", new byte[0]); verifyAll(); // verify all mocks at once } }
EasyMock provides a property mecanisim allowing to alter its behavior. It mainly aims at allowing to use a legacy behavior on a new version. Currently supported properties are:
easymock.notThreadSafeByDefault
easymock.enableThreadSafetyCheckByDefault
easymock.disableClassMocking
Properties can be set in three ways. Each step in the list can overwrite previous ones.
easymock.properties
file set in the classpath default package
EasyMock.setEasyMockProperty
. Constants are available
in the EasyMock
class
EasyMock 3 still has a Class Extension project (although deprecated) to allow an easier migration from EasyMock 2 to EasyMock 3. It is a source not a binary compatibility. So the code will need to be recompiled.
EasyMock 2.1 introduced a callback feature that has been removed in EasyMock 2.2,
as it was too complex. Since EasyMock 2.2, the IAnswer
interface
provides the functionality for callbacks.
EasyMock jar can be used as an OSGi bundle. It exports org.easymock
,
org.easymock.internal
and org.easymock.internal.matchers
packages. However, to import the two latter, you need to specify the poweruser
attribute at true (poweruser=true
). These packages are meant to be
used to extend EasyMock so they usually don't need to be imported.
Sometimes you may need to mock only some methods of a class and keep the normal behavior of others. This usually happens when you want to test a method that calls some others in the same class. So you want to keep the normal behavior of the tested method and mock the others.
In this case, the first thing to do is to consider a refactoring since most of the time this problem caused by a bad design. If it's not the case or if you can't do otherwise because of some development constraints, here's the solution.
ToMock mock = createMockBuilder(ToMock.class) .addMockedMethod("mockedMethod").createMock();
In this case only the methods added with addMockedMethod(s)
will be
mocked (mockedMethod()
in the example). The others will still
behave as they used to. One exception: abstract methods are conveniently mocked by default.
createMockBuilder
returns a IMockBuilder
interface. It contains various methods to
easily create a partial mock. Have a look at the javadoc.
Remark: EasyMock provides a default behavior for Object's methods (equals, hashCode, toString, finalize). However, for a partial mock, if these methods are not mocked explicitly, they will have their normal behavior instead of EasyMock default's one.
It is possible to create a mock by calling one of its constructor. This can be handy when a class method needs to be tested but the class other methods, mocked. For that you should do something like
ToMock mock = createMockBuilder(ToMock.class) .withConstructor(1, 2, 3); // 1, 2, 3 are the constructor parameters
See the ConstructorCalledMockTest
for an example.
For some reason (usually an unsupported JVM), it is possible that EasyMock isn't able to mock a class mock in your environment. Under the hood, class instantiation is implemented with a factory pattern. In case of failure, you can replace the default instantiator with:
DefaultClassInstantiator
which works well with Serializable classes
and otherwise tries to guess the best constructor and parameters to use.IClassInstantiator
.
You set this new instantiator using ClassInstantiatorFactory.setInstantiator()
.
You can set back the default one with setDefaultInstantiator()
.
Important: The instantiator is kept statically so it will stick between your unit tests. Make sure you reset it if needed.
A class mock can also be serialized. However, since it extends a serializable class, this class
might have defined a special behavior using for instance writeObject
. These methods
will still be called when serializing the mock and might fail. The workaround is usually to call
a constructor when creating the mock.
Also, de-serializing the mock in a different class loader than the serialization might fail. It wasn't tested.
equals()
, toString()
, hashCode()
and finalize()
even for class mocking. It means that you cannot record your own behavior for
these methods. This limitation is considered to be a feature
that prevents you from having to care about these methods.
EasyMock has been developed by Tammo Freese at OFFIS. It is maintained by Henri Tremblay since 2007. The development of EasyMock is hosted on SourceForge to allow other developers and companies to contribute.
Class mocking (previously known as EasyMock Class Extension) was initially developed by Joel Shellman, Chad Woolley and Henri Tremblay on the files section of Yahoo!Groups.
Thanks to the people who gave feedback or provided patches, including Nascif Abousalh-Neto, Dave Astels, Francois Beausoleil, George Dinwiddie, Shane Duan, Wolfgang Frech, Steve Freeman, Oren Gross, John D. Heintz, Dale King, Brian Knorr, Dierk Koenig, Chris Kreussling, Robert Leftwich, Patrick Lightbody, Johannes Link, Rex Madden, David McIntosh, Karsten Menne, Bill Michell, Stephan Mikaty, Ivan Moore, Ilja Preuss, Justin Sampson, Markus Schmidlin, Richard Scott, Joel Shellman, Jiří Mareš, Alexandre de Pellegrin Shaun Smith, Marco Struck, Ralf Stuckert, Victor Szathmary, Bill Uetrecht, Frank Westphal, Chad Woolley, Bernd Worsch, Rodrigo Damazio, Bruno Fonseca, Ben Hutchison and numerous others.
Please check the EasyMock home page for new versions, and send bug reports and suggestions to the EasyMock Yahoo!Group. If you would like to subscribe to the EasyMock Yahoo!Group, send a message to<EMAIL_ADDRESS>New in version 3.1:
New in version 3.0:
EasyMock.DISABLE_CLASS_MOCKING
toString
method (2937916)
isNull(Class<T>)
, notNull(Class<T>)
and anyObject(Class<T>)
for easier generic handling (2958636)
For older release notes, see EasyMock 2 and EasyMock 2 Class Extension documentations.


Match Play. 1-1 to 5. How should Red play 42?
pips Red=126 White=137
(CorrectAnswer= 0/0, ErrorScore= 0)
“To kill or be killed?”, that is the question, to paraphrase the bard.
With gammons so important to both players White cannot be allowed his whole roll here so the banana split play bar/21, 3/1* is mandatory. Everything else is a double blunder or worse.
With gammons so important to both players White cannot be allowed his whole roll here so the banana split play bar/21, 3/1* is mandatory. Everything else is a double blunder or worse.
1. Cubeful 2-ply bar/21 3/1* Eq.: +0.172 0.532 0.348 0.020 - 0.468 0.186 0.018 2. Cubeful 2-ply bar/23 5/1* Eq.: +0.059 (-0.113) 0.510 0.340 0.017 - 0.490 0.179 0.014 3. Cubeful 2-ply bar/21 24/22 Eq.: +0.055 (-0.117) 0.546 0.247 0.011 - 0.454 0.133 0.005 4. Cubeful 2-ply bar/21 11/9 Eq.: +0.025 (-0.147) 0.534 0.259 0.012 - 0.466 0.140 0.007 5. Cubeful 0-ply bar/23 11/7 Eq.: -0.138 (-0.310) 0.494 0.236 0.007 - 0.506 0.143 0.006


Hello, I'm
Derek Hernandez
I'm an aspiring Engineer/Developer
I enjoy learning new skills and utilizing them. Hence, I like to build things for computers
I'm an Austin-based aspiring Engineer, that has a broad acadeimic expereicne,
ranging from Computer Security
to full stack development.
About Me
Hello, I'm Derek Hernandez an aspiring Engineer/Developer. My intrest in Engineering and Development has spanned from High School thought College. Even after college I I continue to push my studies by enrolling in a bootcamp.
I graduated college from Texas State with a Bachelors in Computer Science and currrently entrolled in a Full-Stack Bootcamp at The University of Texas at Austin.
Recent tech
- HTML
- CSS
- JavaScript
- Java
- Python
- C++
Projects
Featured!
This Day in Space
Create a website using the skills gained in class, while working with a group.
The website will display results from API'S and display them in a hand-built website.
- Html
- CSS
- JavaScript
Featured!
Mars Rover
A challenge used in interviews. The goal is to take an input file, containing directions and polar cordinates and navigate a plane. Inputs are parsed and our rover will navigate terrain and store each location of rover.
- Python 2
- Data Structures
- Collaboration
Featured!
Pendulum
A common interview question. The goal is to parse through a ordered list and place the correct values in a pendulum order (lowest in the middle, next highest to the right, then left). The goal was to get the Big O Notation as low as possible.
- Python 3
- Data Structures
- Big O Notation
Whats Next?
How to get in touch?
I am activley seeking new oppertunities, such as freelance or open positions.
The best way to get in touch with me is by email.
Feel free to email reguarding opportunities, questions or critiques.


This page contains a JavaScript generic ASN.1 parser that can decode any valid ASN.1 DER or BER structure whether Base64-encoded (raw base64, PEM armoring and begin-base64 are recognized) or Hex-encoded.
This tool can be used online at the address http://lapo.it/asn1js/ or offline, unpacking the ZIP file in a directory and opening index.html in a browser
On the left of the page will be printed a tree representing the hierarchical structure, on the right side an hex dump will be shown.
Hovering on the tree highlights ancestry (the hovered node and all its ancestors get colored) and the position of the hovered node gets highlighted in the hex dump (with header and content in a different colors).
Clicking a node in the tree will hide its sub-nodes (collapsed nodes can be noticed because they will become italic).
ASN.1 JavaScript decoder
Copyright © 2008-2014 Lapo Luchini<EMAIL_ADDRESS>Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ASN.1 JavaScript decoder Copyright © 2008-2014 Lapo Luchini; released as opensource under the ISC license.
OBJECT IDENTIFIER values are recognized using data taken from Peter Gutmann's dumpasn1 program.


Troubleshoot the application
Estimated reading time: 8 minutesYou are viewing docs for legacy standalone Swarm. These topics describe standalone Docker Swarm. In Docker 1.12 and higher, Swarm mode is integrated with Docker Engine. Most users should use integrated Swarm mode — a good place to start is Getting started with swarm mode, Swarm mode CLI commands, and the Get started with Docker walkthrough). Standalone Docker Swarm is not integrated into the Docker Engine API and CLI commands.
It’s a fact of life that things fail. With this in mind, it’s important to understand what happens when failures occur and how to mitigate them. The following sections cover different failure scenarios:
- Swarm manager failures
- Consul (discovery backend) failures
- Interlock load balancer failures
- Web (voting-app) failures
- Redis failures
- Worker (vote-worker) failures
- Postgres failures
- Results-app failures
- Infrastructure failures
Swarm manager failures
In its current configuration, the swarm cluster only has single manager container running on a single node. If the container exits or the node fails, you cannot administer the cluster until you either fix it, or replace it.
If the failure is the swarm manager container unexpectedly exiting, Docker
automatically attempts to restart it. This is because the container was started
with the --restart=unless-stopped
switch.
While the swarm manager is unavailable, the application continues to work in its current configuration. However, you cannot provision more nodes or containers until you have a working swarm manager.
Docker Swarm supports high availability for swarm managers. This allows a single swarm cluster to have two or more managers. One manager is elected as the primary manager and all others operate as secondaries. In the event that the primary manager fails, one of the secondaries is elected as the new primary, and cluster operations continue gracefully. If you are deploying multiple swarm managers for high availability, you should consider spreading them across multiple failure domains within your infrastructure.
Consul (discovery backend) failures
The swarm cluster that you have deployed has a single Consul container on a single node performing the cluster discovery service. In this setup, if the Consul container exits or the node fails, the application continues to operate in its current configuration. However, certain cluster management operations fail. These include registering new containers in the cluster and making lookups against the cluster configuration.
If the failure is the consul
container unexpectedly exiting, Docker
automatically attempts to restart it. This is because the container was started
with the --restart=unless-stopped
switch.
The Consul
, etcd
, and Zookeeper
discovery service backends support various
options for high availability. These include Paxos/Raft quorums. You should
follow existing best practices for deploying HA configurations of your chosen
discover service backend. If you are deploying multiple discovery service
instances for high availability, you should consider spreading them across
multiple failure domains within your infrastructure.
If you operate your swarm cluster with a single discovery backend service and this service fails and is unrecoverable, you can start a new empty instance of the discovery backend and the swarm agents on each node in the cluster repopulate it.
Handling failures
There are many reasons why containers can fail. However, Swarm does not attempt to restart failed containers.
One way to automatically restart failed containers is to explicitly start them
with the --restart=unless-stopped
flag. This tells the local Docker daemon
to attempt to restart the container if it unexpectedly exits. This only
works in situations where the node hosting the container and its Docker daemon
are still up. This cannot restart a container if the node hosting it has failed,
or if the Docker daemon itself has failed.
Another way is to have an external tool (external to the cluster) monitor the state of your application, and make sure that certain service levels are maintained. These service levels can include things like “have at least 10 web server containers running”. In this scenario, if the number of web containers drops below 10, the tool attempts to start more.
In our simple voting-app example, the front-end is scalable and serviced by a load balancer. In the event that one of the two web containers fails (or the node that is hosting it fails), the load balancer stops routing requests to it and sends all requests to the surviving web container. This solution is highly scalable meaning you can have up to n web containers behind the load balancer.
Interlock load balancer failures
The environment that you have provisioned has a single interlock load balancer container running on a single node. In this setup, if the container exits or node fails, the application cannot service incoming requests and the application is unavailable.
If the failure is the interlock
container unexpectedly exiting, Docker
automatically attempts to restart it. This is because the container was started
with the --restart=unless-stopped
switch.
It is possible to build an HA Interlock load balancer configuration. One such way is to have multiple Interlock containers on multiple nodes. You can then use DNS round robin, or other technologies, to load balance across each Interlock container. That way, if one Interlock container or node goes down, the others continue to service requests.

Web (voting-app) failures
The environment that you have configured has two voting-app containers running on two separate nodes. They operate behind an Interlock load balancer that distributes incoming connections across both.
In the event that one of the web containers or nodes fails, the load balancer starts directing all incoming requests to surviving instance. Once the failed instance is back up, or a replacement is added, the load balancer adds it to the configuration and starts sending a portion of the incoming requests to it.
For highest availability you should deploy the two frontend web services
(frontend01
and frontend02
) in different failure zones within your
infrastructure. You should also consider deploying more.
Redis failures
If the redis
container fails, its partnered voting-app
container does
not function correctly. The best solution in this instance might be to configure
health monitoring that verifies the ability to write to each Redis instance. If
an unhealthy redis
instance is encountered, remove the voting-app
and
redis
combination and attempt remedial actions.
Worker (vote-worker) failures
If the worker container exits, or the node that is hosting it fails, the redis containers queue votes until the worker container comes back up. This situation can prevail indefinitely, though a worker needs to come back at some point and process the votes.
If the failure is the worker01
container unexpectedly exiting, Docker
automatically attempts to restart it. This is because the container was started
with the --restart=unless-stopped
switch.
Postgres failures
This application does not implement any for of HA or replication for Postgres. Therefore losing the Postgres container would cause the application to fail and potential lose or corrupt data. A better solution would be to implement some form of Postgres HA or replication.
Results-app failures
If the results-app container exits, you cannot browse to the results of the poll until the container is back up and running. Results continue to be collected and counted, but you can’t view results until the container is back up and running.
The results-app container was started with the --restart=unless-stopped
flag
meaning that the Docker daemon automatically attempts to restart it unless
it was administratively stopped.
Infrastructure failures
There are many ways in which the infrastructure underpinning your applications can fail. However, there are a few best practices that can be followed to help mitigate and offset these failures.
One of these is to deploy infrastructure components over as many failure domains as possible. On a service such as AWS, this often translates into balancing infrastructure and services across multiple AWS Availability Zones (AZ) within a Region.
To increase the availability of our swarm cluster you could:
- Configure the swarm manager for HA and deploy HA nodes in different AZs
- Configure the Consul discovery service for HA and deploy HA nodes in different AZs
- Deploy all scalable components of the application across multiple AZs
This configuration is shown in the diagram below.
This allows us to lose an entire AZ and still have our cluster and application operate.
But it doesn’t have to stop there. Some applications can be balanced across AWS Regions. It’s even becoming possible to deploy services across cloud providers, or have balance services across public cloud providers and your on premises date centers!
The diagram below shows parts of the application and infrastructure deployed across AWS and Microsoft Azure. But you could just as easily replace one of those cloud providers with your own on premises data center. In these scenarios, network latency and reliability is key to a smooth and workable solution.
Related information
The application in this example could be deployed on Docker Universal Control Plane (UCP) which is part of Docker Data Center. To try the application on UCP in your environment, request a free trial. Other useful documentation:
docker, swarm, scale, voting, application, certificates


Counter
Increase
Decrease
Increase Second
{{ counter }} | {{ secondCounter }}
{{ result() }} | {{ output }}


Turkey's SunExpress airline announces order for 10 of 737 Max jets grounded globally after ...
DUBAI, United Arab Emirates - DUBAI, United Arab Emirates (AP) - Turkey's SunExpress airline announces order for 10 of 737 Max jets grounded globally after crashes worth $1.2 billion.
Copyright 2019 The Associated Press. All rights reserved. This material may not be published, broadcast, rewritten or redistributed.


{{member.first}} {{member.last}}
{{member.affiliation}}
@{{member.gh_handle}} on GitHub
Project Jupyter is a non-profit, open-source project, born out of the IPython Project in 2014 as it evolved to support interactive data science and scientific computing across all programming languages. Jupyter will always be 100% open-source software, free for all to use and released under the liberal terms of the modified BSD license.
Jupyter is developed in the open on GitHub, through the consensus of the Jupyter community. For more information on our governance approach, please see our Governance Document.
All online and in-person interactions and communications directly related to the project are covered by the Jupyter Code of Conduct. This Code of Conduct sets expectations to enable a diverse community of users and contributors to participate in the project with respect and safety.
The role of the Jupyter Steering Council is to ensure, through working with and serving the broader Jupyter community, the long-term well-being of the project, both technically and as a community. The Jupyter Steering Council currently consists of the following members (in alphabetical order).
{{member.first}} {{member.last}}
{{member.affiliation}}
@{{member.gh_handle}} on GitHub
{{member.first}} {{member.last}}
Member: {{member.dates}}
@{{member.gh_handle}} on GitHub
Jupyter will always be 100% open source software, free for all to use and released under the liberal terms of the modified BSD license. If you have found Project Jupyter to be useful in your work, research or company, please consider making a donation to the project commensurate with your resources.
All donations will be used strictly to fund the development of Project Jupyter's open source software, documentation and community. Our donations are managed by the NumFOCUS Foundation, which is the legal and fiscal umbrella for the project. NumFOCUS is a 501(c)3 non-profit foundation; if you are subject to US Tax law, your contributions will be tax-deductible.


# SHIT MEN ### Date ----- --- --- --- ----- ## made with #### [reveal.js](https://github.com/hakimel/reveal.js) #### [excalidraw](https://github.com/excalidraw/excalidraw)


Classes |
| class | FastSalience |
| | Machine Perception Primitive: An implementation of the "Fast Salience Using Natural-statistics" algorithm from Butko, et al., 2008. FastSUN is an efficient implementation of Zhang et al.'s SUN algorithm, which is documented in Zhang, et al., 2008 (see Related Publications). More...
|
| class | GentleBoostCascadedClassifier |
| | Machine Perception Primitive: An implementation of a GentleBoost cascaded classifier for full image object search. More...
|
| class | GentleBoostCascadedClassifier2 |
| | Machine Perception Primitive: An implementation of a GentleBoost cascaded classifier for full image object search. More...
|
| class | GentleBoostClassifier |
| | Machine Perception Primitive: An implementation of a GentleBoost classifier for image patch classification. More...
|
| class | GentleBoostClassifier2 |
| | Machine Perception Primitive: An implementation of a GentleBoost classifier for image patch classification. More...
|
| class | InternalMotionModel |
| | Machine Perception Primitive: An implementation of a model that allows a robot to learn about its own motion. More...
|
| class | MIPOMDP |
| | Machine Perception Primitive: An implementation of the "Multinomial IPOMDP" algorithm from Butko and Movellan, 2009 (see Related Publications). More...
|


Data Stewardship¶
Standard Development¶
One of the main products from the NSF EarthCube LinkedEarth grant was the creation of data standards for paleoclimate data.
A data standard is actually comprised of three components:
A representation for the data, such as LiPD and its associated ontology <http://linkedearth.github.io/Ontology/release/index.html>.
A standard vocabulary for the data, which has been developed by NOAA (PaST Thesaurus)
Standard guidelines for reporting of the data, which are provided by PaCTS crowdsourced standard for the reporting of paleoclimate data (PaCTS). The work involved 135 researchers worldwide and was highlighted by the American Geophysical Union (AGU)’s research highlights and at the Fall Meeting 2019.


|
GiroDeGado
|
This file contains the unit tests of the Cattle class for the GiroDeGado software. More...
#include <windows.h>
#include <assert.h>
#include <math.h>
#include "../../includes/cattleImpl.h"
#include "../../includes/farm.h"
Go to the source code of this file.
Functions | |
| void | unit_cattle_constructor () |
| Unit tests. More... | |
| void | unit_cattle_copy_constructor () |
| void | unit_cattle_destructor () |
| void | unit_cattle_getEarring (Farm *f) |
| void | unit_cattle_setEarring (Farm *f) |
| void | unit_cattle_getBreed (Farm *f) |
| void | unit_cattle_setBreed (Farm *f) |
| void | unit_cattle_getAcquisitionDate (Farm *f) |
| void | unit_cattle_setAcquisitionDate (Farm *f) |
| void | unit_cattle_getBirthDate (Farm *f) |
| void | unit_cattle_setBirthDate (Farm *f) |
| void | unit_cattle_getFather (Farm *f) |
| void | unit_cattle_setFather (Farm *f) |
| void | unit_cattle_getMother (Farm *f) |
| void | unit_cattle_setMother (Farm *f) |
| void | unit_cattle_getWeight (Farm *f) |
| void | unit_cattle_setWeight (Farm *f) |
| void | unit_cattle_getValue (Farm *f) |
| void | unit_cattle_setValue (Farm *f) |
| void | unit_cattle_assingmentOperator () |
| void | run_unit_tests_cattle (Farm *f) |
This file contains the unit tests of the Cattle class for the GiroDeGado software.
| void run_unit_tests_cattle | ( | Farm * | f | ) |
Function prototype for the function that runs all the unit tests of the Cattle class.
| void unit_cattle_assingmentOperator | ( | ) |
Function prototype for the CattleHandle class' assingment operator unit test.
| void unit_cattle_constructor | ( | ) |
| void unit_cattle_copy_constructor | ( | ) |
Function prototype for the CattleHandle class' copy constructor unit test.
| void unit_cattle_destructor | ( | ) |
Function prototype for the Cattle class' destructor unit test.
| void unit_cattle_getAcquisitionDate | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getAcquisitionDate() unit test.
| void unit_cattle_getBirthDate | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getBirthDate() unit test.
| void unit_cattle_getBreed | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getBreed() unit test.
| void unit_cattle_getEarring | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getEarring() unit test.
| void unit_cattle_getFather | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getFather() unit test.
| void unit_cattle_getMother | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getMother() unit test.
| void unit_cattle_getValue | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getValue() unit test.
| void unit_cattle_getWeight | ( | Farm * | f | ) |
Function prototype for the Cattle class' method getWeight() unit test.
| void unit_cattle_setAcquisitionDate | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setAcquisitionDate() unit test.
| void unit_cattle_setBirthDate | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setBirthDate() unit test.
| void unit_cattle_setBreed | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setBreed() unit test.
| void unit_cattle_setEarring | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setEarring() unit test.
| void unit_cattle_setFather | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setFather() unit test.
| void unit_cattle_setMother | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setMother() unit test.
| void unit_cattle_setValue | ( | Farm * | f | ) |
Function prototype for the Cattle class' method setValue() unit test.


Techniche is one of the largest college tech fests in the country, with more than 50,000 participants each year. But every year, a new website was built, which resulted in inconsistent, slow, and confusing registration experience.
I took upon an ambitious challenge to design the browsing and registration experience for users and to change the team's approach towards integrating solutions for effective internal manegement.
Over the years, Techniche has served as a distinguished platform for entrepreneurs, innovators, and technocrats to showcase their ability while allowing students to learn by engaging in these events. The Techniche website has become the essential bridge in connecting participants and techniche core team.
But it failed to evolve. Nonresponsiveness, slow loading time, complex architecture, and new partner's integration resulted in decreased digital registrations, an increase in the number of queries, and extensive manual work to manage registration data.
The techfest site became an irony to the brand.
Our goal was to deliver a consistent and straightforward experience. Each event in Techniche is unique in it's functioning. Inherently, this leads to different launch timelines and exclusive functionalities. Inevitably, everything had to be done in sprints while maintaining consistency.
Our High-level Goals were :
1. Developing a simple, elegant, and usable site.
2. Responsive Design
3. Optimized for Quick Loading
4. Easy to find on the web
Every journey has barriers, and our's were -
1. Starting From Scratch
Modification of the previous code was impossible for us. The voluntary student team's development skills were under development. We had to start fresh, for design as well as development.
2. Short Time to Develop and Launch
Four months is a short time to design and deliver a website. We began in November when the team started to learn how to build a website and had to launch the site by 1st week of March.
3. Balancing Academics
The academic deliverables were the priority. We had to find a balance between academics and Techniche.
I was the Head of the Web Operations in Techniche. I was responsible for developing the project timeline, ensuring on-time deliverables, gathering requirements from sponsors, partners, and other Techniche verticals, registration management, and payment query resolutions from November 2017 to September 2018. I led a team of 3 enthusiastic juniors with different engineering streams and collaborated with two designers for concept review and site improvement.
Based on our 2017 edition experience, we found that participants were facing difficulty finding already-present information. Participants emailed us to get that information. We set out to discover why.
Based on analytics, we knew 50% of participants used mobile and other 50%, laptop/tablet to visit our platform. We went around college people to see how they use the website on these devices.
1. Slow connectivity and massive site:
Indian cellular connections are slow, and hence site almost was unable to load on the mobile browser.
Even on the college network (with fast internet), it took more than 10 seconds to load on the laptop
2. Classic Case of Inconsistencies
a. Navigation
How often do you see two type of navigation? Rarely right? And we had 3 different navigation structures making it difficult to find the right information quickly.
b. Design Language
3. Extra Unnecessary Information and Usabilty Issues on Smartphones
Since most of our users came through social media posts, they came with interest in specific events. Displaying all information upfront forced them to browse through extra unnecessary information, thus slowing down them. This became painful on smartphones where a users had to scroll multiple times to find his interested topic.
4. One Label for Everything
Events, competitions, and famous Technothlon exam, everything was put under events label. Inevitably users were unable to understand the differences.
Our research gave insight that users had different intentions:
1. Compete on a national level
2. Showcase their impressive work and get exposure
3. Learn from the experts
4. Participate in fun and have social interaction
For the above problem the critical metrics used were
1. Digital Registrations Count & Revenue
2. Digital Footfall
3. Number of queries raised through email for existing information
There were many solutions to the problem, yet we picked a solution with the least development effort and higher impact.
A. Browsing Activities
1. The new Techniche site's Home page allows users to explore activities based on their intent. For example: a user wishes to compete can directly look at all competitions with 1 click. A single glance tells everything planned for Techniche in 2018.
2. With the mobile-first approach, irrespective of device, it got easier to navigate. Every component excluded hover interaction, making it more usable on mobile. The side navigation allows easy navigation from one activity to any other, with three clicks at max.
3. Consistent design language made it easier to predict where to find the information on similar pages. Also, our efforts drastically reduced, and everything appeared as a part of a big home.
B. Registration Experience
1. Wherever possible, in consultation with event teams, the fields in forms were reduced to make registration quick. When form fields were needed, the form was segregated into sections to avoid overwhelming participants and losing registrations.
2. We use 3rd party vendors for buying event tickets and payment handling. Their system required users to fill the form and then make payment. With form on our site, the user had to enter the same details twice. The marketing head and I discussed with our partner and developed a Techniche exclusive API allowing payment by filling one form on our site, saving effort and time.
1. For Guwahati Half Marathon, the BIB distribution, digital record of the BIB number against participant's name, and new registrations took more than 2 hours. It often resulted in a delayed start of the marathon.
2. I designed a mechanism that completed everything within 1.25 hours. Here's how we handled this challenge.
NOTE: Events start at 6:00 am and all the team was awake the whole night for settign up the arena
1. We divided the arena and number of desks based on each category's online registration traffic and expected offline registration traffic. This allowed optimized distribution of all participants.
2. Participants come randomly, so instead of assiging BIB number during online registration, we allocated the BIB numbers on the go. This removed delay that could be caused because of searching the BIB in the pile. The 3rd party vendors had pre assigned BIB numbers for some technical limitation and that resulted in some delays.
3. By allowing each lane to register or just update BIB number, we avoided rearranging participant who would have accidently been standing in the wrong queue. Better experience for them and a lot of time and energy saved for us.
Listen to how this tool helped in the Missing Child Incident
Users Accessed The Website
Increase in Digital Registrations on an Average
Reduction in Query Emails for Existing Information
Users now used Smartphone for Access
1. User Research
a. From my experience of two years as a tech-fest organizer, query mails for existing information were troubling. That triggered the whole process of researching -
i. What's making it difficult to find information?
ii. Why are digital registrations less or nearby offline registration count?
b. But before trying to find answers, it was important to understand our user base and different contexts of use. So, I mapped them out.
c. Traditionally Techniche website has seldom been designed keeping in mind users. Using customizable templates or libraries which often looked fancy, had to just wrap around the vast requirements of different activities in Techniche. This often led to shortening writeups, hiding information behind hover interactions etc, making finding the right information difficult. I tried to educate my subordinates always to avoid 'one size fits all' concept.
2. Benchmarking
One important aspect was to see how other similar techfest sites are designed and a quick strength and weekness analysis gave us some design directions.
3. Use Case Diagram and IA
(Developed in Collaboration with internal team)
4. Whiteborading concepts, wireframes and development
a. Before beginning to design wireframe, we had already set up basic design directions such as mobile-friendly interactions, optimized js libraries, avoid overload with information etc.
b. I did dirty wireframing concepts and started developing the website with color palate used by the creatives team.
5. Testing with Team Members
Did internal testing to find bugs and whether the team members were able to access information for their own module easily and also whether they can browse other event information.


Commuter train hits motor home in fiery collision near Los Angeles
The crash caused major delays during rush hour.
A motor home stopped on the tracks has been hit by a commuter train and burst into flames near Los Angeles.
There were no immediate reports of major injuries following the fiery collision at around 5.30am at a rail crossing intersection in an industrial area of Santa Fe Springs.
The crash caused major delays during rush hour.
Passengers and crew on Metrolink’s OC Line 681 were safely evacuated.
Passenger Ryan Hajek said he felt the train operator slam on the brakes as it approached the crossing.
Mr Hajek told TV station KABC-TV: “The lights inside went dark, so we knew something went wrong, I knew we crushed into something. As we stopped, I saw all the debris of what looked like a car on the side of the tracks, and I knew then that we had hit something.”
Four people on board complained of pain and were treated at the scene.
Investigators will try to determine why the motor home was stopped on the tracks.
Fire crews doused the flames, which gutted the motor home and charred a rail carriage on a freight train stopped on a parallel track.
The freight train was unable to stop in time and ran over some of the crash debris, according to Lena Kent, spokeswoman for BNSF, which maintains tracks in the area.
Police were looking for four people seen running from the tracks just prior to the impact, but it was not immediately known if they were coming from the motor home.
The collision occurred at a crossing equipped with gates and flashing lights, Ms Kent said. It was not clear if the motor home tried to drive around the gates, she said.
The Metrolink train with five passenger carriages was heading north from Orange County when the crash happened about 15 miles south-east of downtown Los Angeles.
Buses were ordered to take 120 evacuated passengers to Union Station in Los Angeles. Widespread delays were expected on Metrolink’s Orange County and 91/Perris Valley lines.


Mon Apr 28, 2008
I mentioned in part one of this series that 80% of jobs can only be found in that elusive place called “the hidden job market.” About 20% of those gigs can be gotten through employment services, cold calling, and other tactics, such as information interviews. But the other 60% are landed through referrals. That makes networking your only way to access a big chunk of the job market.
So how do you rustle up some contacts in Vancouver, a city that has a reputation for being a tad on the chilly side?
Well, a great way to get started is to join the local West coast STC chapter. Volunteering for them is a great way to make some contacts, probably even more so that just showing up for meetings.
Sign up for T-Net direct, a weekly newsletter that tells you what BC technology events are happening around town. Go to events outside of your field, where you don’t expect to see a lot of other writers. That way you’ll be more unique and make more valuable connections than you would hanging out with other writers who are looking for work.
Let everyone know you’re looking for work, and if your cousin’s roommate’s girlfriend tells you her brother is a technical writer, ask for his contact info and set up an informational interview. Having some connection, no matter how distant, is always better than interviewing a complete stranger.
Most importantly, don’t network to find work. Network to be social and meet people. If you approach everybody as a possible job lead, they’ll smell the sleaze on you a mile away.
So how do you ace the tech-writing interview? That’ll be in part 3, coming this Friday.


{% extends "auctions/layout.html" %} {% block body %} {% for i in items %}
Description: {{i.description}}
Created {{i.time}} by {{i.owner}}


06 May 1997
Disease Outbreak Reported
Since the end of January, a cholera outbreak with increasing numbers of cases and deaths has occurred in the country. The first cases reported were in Dar es Salaam and then spread to seven other areas. Vibrio cholerae El Tor Ogawa has been confirmed. As of 30 April 1997, nearly 3000 cases with over 100 deaths had been reported. These reports only related to cases which were admitted to hospitals. Cholera cases were also reported in Zanzibar where there were 30 cases with 2 deaths since the end of March.
The Tanzanian Government, WHO and UNICEF are organising an emergency strategy to combat cholera. WHO will also provide US $15 000 to assist the government to implement control activities (health education, training etc.) and to purchase supplies and equipment. WHO will send consultants to provide technical support if requested by the government.


suspend fun map(from: BaseResponse<CharacterResponse>): CharacterDetail
Transform network response to CharacterDetail.
from
- Network characters response.
NoSuchElementException
- If the response results are empty.
Return
List of parsed characters items.


About Me
Full stack web developer with a long history in Hospitality. Recently worked in a high
intensity pre-theatre, fine dining restaurant dealing with large guest counts. I showed that
I have exceptional time management skills combined with great organizational skills to keep
my guests on time and comfortable. Being a head staff member, I would close the business on
lucrative nights, keeping high-profile clients captivated and carefree. Passionate about
creating and inventing new, never thought about products. Excited to bring my passion into
the workspace with my newly found knowledge of JavaScript, CSS, and React.js. I have a
fondness for creating products that are pleasing to the eye and highly functional at the
same time. Working my way through college and a conservatory taught me to keep my composure
while under pressure. I am looking to be a part of a team to design and create web
applications that will benefit the masses.
On a more personal note, I have a big passion for food. Cooking and bringing people together
with a great meal is one of my favourite things. I love the outdoors including camping,
hiking, kayaking and snowbaording. From a young age, I have spent many sleepless nights
playing video games. This sparked my interest in coding. I have always dreamed of being a
part of a team that creates one of the things that has kept me endlessly entertained. With
my knowledge that I have received from the University of Pennsylvania, I plan to rock the
tech world and am very excited to begin my endeavour.
I've attended college at Rowan College at Burlington County in New Jersey where I studied
for my first two years. I transitioned into my acting career in New York City at the
American Muscial and Dramatic Academy. While training at this conservatory, I fell deeper in
love with the restaurant scene and began to bartend for some of the best restaurants in New
York City. I learned how to be a true team player and what it means to be a part of a
well-oiled machine. Working in New York's restaurant scene, one acquires knowledge that is
very hard to come by. It is a different animal when it comes to this stuff. New Yorkers take
their food pretty seriously! My experience in this field has given me the resources to take
what I know from the real world and apply it to our ever expanding web. The world is
changing and advancing at a rapid pace, and it takes someone that is quick-witted and
competent to get things done and done right.