If I make a test that should throw a fatal error, how can I handle that? For instance, how can I write this test to ensure a variable is deleted properly:
[Test]
public static void TestScope()
{
String str;
{
str = scope .();
}
str.ToUpper(); // str should be marked as deleted here
}
You can parameterize the Test attribute as Test(ShouldFail=true).
The test process first runs all tests that shouldn't fail, then runs all tests that should. If any tests that should fail don't, the remaining should-fail tests are still run.
For instance, testing this class:
class Program
{
[Test(ShouldFail=true)]
public static void TestScopeShouldFailButSucceeds()
{
String str;
{
str = scope:: .();
}
str.ToUpper(); // will not fail
}
[Test(ShouldFail=true)]
public static void TestScopeShouldFail()
{
String str;
{
str = scope .();
}
str.ToUpper(); // will fail
}
[Test]
public static void TestScopeShouldNotFail()
{
String str;
{
str = scope:: .();
}
str.ToUpper(); // will not fail
}
public static void Main()
{
}
}
...will first successfully complete TestScopeShouldNotFail, then will unexpectedly complete TestScopeShouldFailButSucceeds, then will expectedly fail in TestScopeShouldFail. Thus, it will produce one failed test for TestScopeShouldFailButSucceeds.
Related
With mockito-inline how to test static function (with stubbing other static function), or mock/stub some internal depended class?
Here is the sample:
Having a class Util which internally depending on java.security.MessageDigest
package java.security;
public abstract class MessageDigest extends MessageDigestSpi
... ...
public byte[] digest() {
byte[] result = engineDigest();
return result;
}
}
and the container class has a few static functions to be tested
public class Util {
public static byte[] getStringDigest(#NonNull String text, #NonNull String algorithm, #NonNull String charSet) {
if (text == null) {
return null;
}
MessageDigest messageDigest; //<== depend on
try {
messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(text.getBytes(charSet));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
return null;
}
return messageDigest.digest();
}
public static String generateId(#NonNull String s) {
byte[] sha1Byte = getStringDigest(s, "SHA-1", "UTF-8");
if (sha1Byte == null) {
return s;
}
// otherwise build the id
String id = buildId(sha1Byte);
return id;
}
}
would like to test the Utils.generateId(#NonNull String s) with stubbing getStringDigest() returning null, so that sometext is expected to return.
since it is static function so it was tested with powermock.
#Test
public test_util_1{
PowerMockito.mockStatic(MessageDigest.class);
String sometext = "sometext";
PowerMockito.when(Util.getStringDigest(sometext, "SHA-1", "UTF-8")).thenReturn(null);
assertEquals(sometext, Util.generateId(sometext));
}
with mock stub, when Util.getStringDigest() is called null is returned.
It worked fine.
now the mockito-inline supports testing static function (and it has problem to mix with powermockito2 when testing kotlin etc.) so the powermock is removed.
Tried with mockito-inline 3.8.0
#Test
public void test_util_1() {
String sometext = "sometext";
try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
utilMoc.when(() -> Util.getStringDigest(sometext, "SHA-1", "UTF-8"))
.thenReturn(null);
assertEquals(sometext, Util.generateId(sometext));
}
got error:
java.lang.AssertionError: Unexpected value
Expected :sometext
Actual :null
the Util.generateId(sometext) returns null (not the sometext).
when using assertEquals(sometext, sutilMoc.generateId(sometext)); it cannt compile and says cannt resolve the generateId().
How to use mockito-inline to test the static function?
Or if there is way to mock/stub the depended abstract class MessageDigest for stub the digest() to return null, but dont know is it possible?
found a way to make the test work (using .thenCallRealMethod()),
but still not find a way to mock the depended class which is instantiated inside the static function. if anyone knows a solution for that?
#Test
public void test_util_1() {
String sometext = "sometext";
try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
utilMoc.when(() -> Util.getStringDigest(anyString(), anyString(), anyString()))
.thenReturn(null);
// need to tell mock to call the original, otherwise a default mocked stub will be called
utilMoc.when(() -> Util.generateId(anyString()))
.thenCallRealMethod();
assertEquals(sometext, Util.generateId(sometext));
}
In the code Google Mock test snippet there is an EXPECT_CALL that returns True and an argument reference for 200 times.
How can I let the test only return True every nth time. For example return True each 10th call and otherwise return False.
class MockHandler : public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
}
TEST(TestDispatcher, HandlePing)
{
auto mockedHandler = make_unique<MockHandler>();
Msg rxMsg = { REQUEST::REQ_PING, sizeof(DefaultMsg_t), rxMsg.rx,(uint8_t*)"0"};
EXPECT_CALL(*mockedHandler,
RxMsg(_)).Times(checkValue).WillRepeatedly(
DoAll(SetArgReferee<0>(rxMsg), Return(TRUE)));
Dispatcher dispatcher(10, mockedHandler);
for (int i = 0; i < 199; i++)
{
dispatcher.RunToCompletion();
}
}
There are few approaches that might work for you. I like the solution with Invoke as a default action, because it is the most flexible. You didn't provide mcve in your question, so I wrote very simple implementations for the classes you use. Also you made a mistake using unique_ptr for the mock. In 99% of cases is must be shared_ptr, because you are sharing it between testing environment and your System Under Test.
class Msg {};
class Handler {
public:
virtual bool RxMsg(Msg &msg) = 0;
};
class MockHandler: public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
};
class Dispatcher {
public:
Dispatcher(std::shared_ptr<Handler> handler): h_(handler) {}
void run() {
Msg m;
std::cout << h_->RxMsg(m) << std::endl;
}
private:
std::shared_ptr<Handler> h_;
};
class MyFixture: public ::testing::Test {
protected:
MyFixture(): mockCallCounter_(0) {
mockHandler_.reset(new MockHandler);
sut_.reset(new Dispatcher(mockHandler_));
}
void configureMock(int period) {
ON_CALL(*mockHandler_, RxMsg(_)).WillByDefault(Invoke(
[this, period](Msg &msg) {
// you can also set the output arg here
// msg = something;
if ((mockCallCounter_++ % period) == 0) {
return true;
}
return false;
}));
}
int mockCallCounter_;
std::shared_ptr<MockHandler> mockHandler_;
std::unique_ptr<Dispatcher> sut_;
};
TEST_F(MyFixture, HandlePing) {
configureMock(10);
for (int i = 0; i < 199; i++) {
sut_->run();
}
}
At the beginning of each test you should call configureMock method that will Invoke ON_CALL macro setting the default action for your mock. Function passed to Invoke can be any function matching the signature of the method you are overwriting. In this case it;s a function that counts how many times mock has already been called and returns appropriate value. You can also assign some particular object to the msg output argument.
I'm trying to use CppUnit to test a method that should execute some code only the first time it is called.
class CElementParseInputTests: public CppUnit::TestFixture {
private:
CElement* element;
public:
void setUp() {
element = new CElement();
}
void tearDown() {
delete element;
}
void test1() {
unsigned int parsePosition = 0;
CPPUNIT_ASSERT_EQUAL(false, element->parseInput("fäil", parsePosition));
}
void test2() {
unsigned int parsePosition = 0;
CPPUNIT_ASSERT_EQUAL(false, element->parseInput("pass", parsePosition));
}
The recursive method I want to test:
bool CElement::parseInput(const std::string& input, unsigned int& parsePosition) {
static bool checkedForNonASCII = false;
if(!checkedForNonASCII) {
std::cout << "this should be printed once for every test case" << std::endl;
[...]
checkedForNonASCII = true;
}
[...]
parseInput(input, parsePosition+1)
[...]
}
Since the object is recreated and then destroyed for every test case, I would expect that the string "this should be printed once for every test case" would be printed twice when running the tests, but it's only printed once. What have i missed?
That's what static local variables supposed to do.
Variables declared at block scope with the specifier static have static storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.
That means checkedForNonASCII will be initialized to false only once for the 1st call. For further calls the initialization is skipped; i.e. checkedForNonASCII won't be initialized to false again.
What the other answer said. But this is probably what you really want:
bool CElement::parseInput(const std::string& input, unsigned int& parsePosition)
{
[...] // your code for validating ascii only characters goes here
if (hasNonAsciiCharacters) {
return false;
}
return parseInputInteral(input, parsePosition);
}
bool CElement::parseInputInternal(const std::string& input, unsigned int& parsePosition)
{
[...]
parseInputInternal(input, parsePosition+1);
[...]
return result;
}
I have a mocked function that when I run in a unit test with the anything matcher ('_') the unit test fails because GMock can't find a matched function.
Here is my mocked class and function:
class MockedClass {
public:
MockedClass() {};
~MockedClass() {};
MOCK_METHOD1(unregisterClient, bool(const ThriftClient& tClient));
};
class ConnectionClass {
public:
ConnectionClass() {};
~ConnectionClass() {};
bool unregisterClient(ThriftClient& tClient)
{
bool ret = false;
if (mock_ != NULL)
ret = mock_->unregisterClient(tClient);
return ret;
}
static MockedClass *mock_;
};
MockedClass *ConnectionClass::mock_ = NULL;
Here is the function under test:
class RealObject {
public:
RealObject(ConnectionClass &cc);
void unregister();
private:
ConnectionClass &cc_;
ThriftClient tClient_;
}
RealObject::RealObject(ConnectionClass &cc) {
cc_ = &cc;
}
void RealObject::unregister() {
cc_->unregisterClient(tClient_);
}
Here is the test function:
TEST_F(Test, UnregisterTest) {
MockedClass mclass;
ConnectionClass cc;
cc.mock_ = &mclass;
RealObject obj(cc);
EXPECT_CALL(mclass, unregisterClient(_)).WillOnce(Return(true));
obj.unregister(); // Calls mocked function
}
Here is the failure message:
Test.cpp:142: Failure Actual function call count doesn't match
EXPECT_CALL(mclass, unregisterClient(_))...
Expected: to be called once
Actual: never called - unsatisfied and active
I have also tried:
EXPECT_CALL(mclass, unregisterClient(Matcher<const ThriftClient&>(_))).WillOnce(Return(true));
EXPECT_CALL(mclass, unregisterClient(An<const ThriftClient&>())).WillOnce(Return(true));
All with the same failure message.
Why am I getting this failure message? I don't understand why GMock can't match the function call.
I have a static method with ref parameters in my legacy (untestable) dll. I am trying to write unit tests for a class that calls into this method.
public static class Branding
{
...
...
static public bool GetBranding(Int32 providerId,
Int32 employerId,
string brandingElement,
ref string brandingValue)
...
...
}
I need help writing a shim statement for this call
ShimBranding.GetBrandingInt32Int32StringStringRef =
( providerId, employerId, element, { ====> WHAT GOES HERE <===== } )
=>
true;
Thanks!
using (ShimsContext.Create())
{
ShimBranding.GetBrandingInt32Int32StringStringRef =
(int providerId, int employerId, string brandingElement, ref string brandingValue) =>
{
brandingValue = "Blah";
return true;
};
}